From 345b5438717dcda9c9ed8cd4e203d832c2970c1b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 24 Sep 2019 00:59:02 +0900 Subject: [PATCH 001/402] =?UTF-8?q?Translator=20API=20=E3=81=AE=E3=82=A2?= =?UTF-8?q?=E3=82=AF=E3=82=BB=E3=82=B9=E3=83=88=E3=83=BC=E3=82=AF=E3=83=B3?= =?UTF-8?q?=E5=8F=96=E5=BE=97=E3=81=AB=E5=A4=B1=E6=95=97=E3=81=97=E3=81=9F?= =?UTF-8?q?=E5=A0=B4=E5=90=88=E3=81=AF=E4=BE=8B=E5=A4=96=E3=82=92=E7=99=BA?= =?UTF-8?q?=E7=94=9F=E3=81=95=E3=81=9B=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Api/MicrosoftTranslatorApi.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OpenTween/Api/MicrosoftTranslatorApi.cs b/OpenTween/Api/MicrosoftTranslatorApi.cs index 4736df3dd..51e8abb21 100644 --- a/OpenTween/Api/MicrosoftTranslatorApi.cs +++ b/OpenTween/Api/MicrosoftTranslatorApi.cs @@ -117,6 +117,8 @@ public async Task UpdateAccessTokenIfExpired() using var response = await this.Http.SendAsync(request) .ConfigureAwait(false); + response.EnsureSuccessStatusCode(); + var accessToken = await response.Content.ReadAsStringAsync() .ConfigureAwait(false); From b591594a119ec1e6ab4ad8979844332422ee31f1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 24 Sep 2019 01:00:08 +0900 Subject: [PATCH 002/402] =?UTF-8?q?OpenTween=20v2.4.0=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 26 +++++++++++----------- OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index d933d2581..c08514ba2 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.3.1.1")] +[assembly: AssemblyFileVersion("2.4.0.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 112479799..a798bc9a1 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace OpenTween.Properties { // または Visual Studio のようなツールを使用して自動生成されました。 // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -652,18 +652,18 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Ver 2.3.2-dev(2019/xx/xx) - /// - ///==== Ver 2.3.1(2019/04/22) - /// * FIX: 2019/5/20に予定されているTwitter APIの仕様変更によりエラーが発生する問題を修正 - /// - OpenTween v2.3.0 までのバージョンは2019/5/20以降に使用できなくなる可能性があります - /// * FIX: 絵文字を含むツイートの非公式RTで余分なHTMLタグが混入する不具合を修正 (thx @380Nayuta!) - /// - ///==== Ver 2.3.0(2019/04/08) - /// * CHG: 投稿欄にフォーカスしている間は一部のショートカットを無効にします (thx @pitermach, @lukaszgo1!) - /// - 対象となるショートカットは Ctrl+Alt+S (Fav+RT), Ctrl+Alt+R (Fav+非公式RT), Ctrl+Alt+H (ユーザー指定のURLを開く) の3つです - /// - AltGrキーを使う言語のキーボートとショートカットキーが重複する問題への対処です - /// * CHG: Micr [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + ///==== Ver 2.4.0(2019/09/24) + /// * NEW: Twemoji 12.0.0 に対応しました + /// - Unicode 12.0 で追加された絵文字が表示されるようになります + /// * CHG: DMの送信が完了したらDirectタブに送信したDMを即座に反映する + /// * CHG: htn.to の短縮URLを展開する際に強制的にHTTPSを使用する + /// * CHG: OpenTween内部で動作するタイマーの使用方法を見直し + /// - 従来まで毎秒5回程度のタイマーイベントが常に発生していたのを、無操作時かつ発言一覧の更新がない間はほぼゼロになるよう改善しました + /// * FIX: Twemojiを有効にすると絵文字の後に余分な文字が表示される場合がある不具合を修正 + /// * FIX: Tumblrのサムネイル表示時にエラーが表示される場合がある不具合を修正 + /// * FIX: 発言内URLを開く(Ctrl+E)でURLにマルチバイト文字を含むとエラーが発生する場合がある不具合を修正 + /// * FIX: 英語版のメッセージの誤りを修正 (thx @Tan90909090!) + /// [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index c1365d7c8..b3002ed3c 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Ver 2.3.2-dev(2019/xx/xx) +==== Ver 2.4.0(2019/09/24) * NEW: Twemoji 12.0.0 に対応しました - Unicode 12.0 で追加された絵文字が表示されるようになります * CHG: DMの送信が完了したらDirectタブに送信したDMを即座に反映する From 47218c2958f3cfda68ecc02e70186d3f34c72778 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 24 Sep 2019 01:02:39 +0900 Subject: [PATCH 003/402] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.4.1-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 5 +++-- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index c08514ba2..f8ca9e457 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.4.0.0")] +[assembly: AssemblyFileVersion("2.4.0.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index a798bc9a1..1fe63f499 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -652,6 +652,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Ver 2.4.1-dev(2019/xx/xx) + /// ///==== Ver 2.4.0(2019/09/24) /// * NEW: Twemoji 12.0.0 に対応しました /// - Unicode 12.0 で追加された絵文字が表示されるようになります @@ -662,8 +664,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * FIX: Twemojiを有効にすると絵文字の後に余分な文字が表示される場合がある不具合を修正 /// * FIX: Tumblrのサムネイル表示時にエラーが表示される場合がある不具合を修正 /// * FIX: 発言内URLを開く(Ctrl+E)でURLにマルチバイト文字を含むとエラーが発生する場合がある不具合を修正 - /// * FIX: 英語版のメッセージの誤りを修正 (thx @Tan90909090!) - /// [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: 英語版 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index b3002ed3c..ff05d45d8 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Ver 2.4.1-dev(2019/xx/xx) + ==== Ver 2.4.0(2019/09/24) * NEW: Twemoji 12.0.0 に対応しました - Unicode 12.0 で追加された絵文字が表示されるようになります diff --git a/appveyor.yml b/appveyor.yml index 05584203c..dde3d23cd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.3.1.{build} +version: 2.4.0.{build} os: Visual Studio 2019 From d37c0adb358c3e08ef498a22ae634b456071553a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 24 Sep 2019 02:33:05 +0900 Subject: [PATCH 004/402] =?UTF-8?q?ViewTabBottom=E3=81=8Cfalse=E3=81=A0?= =?UTF-8?q?=E3=81=A8=E8=B5=B7=E5=8B=95=E6=99=82=E3=81=AB=E3=82=A8=E3=83=A9?= =?UTF-8?q?=E3=83=BC=E3=81=8C=E7=99=BA=E7=94=9F=E3=81=99=E3=82=8B=E4=B8=8D?= =?UTF-8?q?=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3=20(thx=20@mulsys!?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TabInformations.SelectTab が呼ばれる前に TweenMain.SetTabAlignment メソッド内で選択中のタブを参照したことが原因 Fixes: bf2159ff ("現在表示中のタブをTabPageではなくタブ名で管理, TweenMain._curTab フィールドを廃止") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index ff05d45d8..edcf7faeb 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Ver 2.4.1-dev(2019/xx/xx) + * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) ==== Ver 2.4.0(2019/09/24) * NEW: Twemoji 12.0.0 に対応しました diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 0109c2951..6a2028315 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1127,8 +1127,6 @@ private void TweenMain_Load(object sender, EventArgs e) ApplyListViewIconSize(SettingManager.Common.IconSize); //<<<<<<<<タブ関連>>>>>>> - // タブの位置を調整する - SetTabAlignment(); //デフォルトタブの存在チェック、ない場合には追加 if (this._statuses.GetTabByType() == null) @@ -1154,6 +1152,9 @@ private void TweenMain_Load(object sender, EventArgs e) this._statuses.SelectTab(this.ListTab.SelectedTab.Text); + // タブの位置を調整する + SetTabAlignment(); + MyCommon.TwitterApiInfo.AccessLimitUpdated += TwitterApiStatus_AccessLimitUpdated; Microsoft.Win32.SystemEvents.TimeChanged += SystemEvents_TimeChanged; From 03835b2189cd3a42bd2c9e3413b4161e3786b455 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 24 Sep 2019 04:12:08 +0900 Subject: [PATCH 005/402] =?UTF-8?q?string.IsNullOrEmpty=20=E3=81=AE=20null?= =?UTF-8?q?able=20annotation=20=E3=81=82=E3=82=8A=E7=89=88=E3=81=AE?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit VS16.3 に同梱されているRoslynから string.IsNullOrEmpty などのメソッドに対する アノテーションがハードコードされなくなったため、独自に代替のメソッドを用意する必要がある --- OpenTween/Api/BitlyApi.cs | 4 +- OpenTween/Api/MicrosoftTranslatorApi.cs | 2 +- OpenTween/Api/TwitterApi.cs | 4 +- OpenTween/Api/TwitterApiStatus.cs | 2 +- OpenTween/Api/TwitterStreamObservable.cs | 2 +- OpenTween/AppendSettingDialog.cs | 4 +- OpenTween/ApplicationEvents.cs | 2 +- OpenTween/AtIdSupplement.cs | 6 +- OpenTween/Connection/Networking.cs | 2 +- OpenTween/Connection/OAuthUtility.cs | 4 +- OpenTween/Connection/TwitterPhoto.cs | 2 +- OpenTween/EventViewerDialog.cs | 2 +- OpenTween/FilterDialog.cs | 14 +-- OpenTween/Growl.cs | 2 +- OpenTween/HashtagManage.cs | 14 +-- OpenTween/ImageListViewItem.cs | 2 +- OpenTween/ListManage.cs | 4 +- OpenTween/MediaSelector.cs | 14 +-- OpenTween/Models/MediaInfo.cs | 2 +- OpenTween/Models/PostFilterRule.cs | 26 ++--- OpenTween/Models/PublicSearchTabModel.cs | 2 +- OpenTween/Models/TabInformations.cs | 2 +- OpenTween/Models/UserTimelineTabModel.cs | 2 +- OpenTween/MyCommon.cs | 8 +- OpenTween/NativeMethods.cs | 2 +- OpenTween/SearchWordDialog.cs | 6 +- OpenTween/Setting/Panel/CooperatePanel.cs | 2 +- OpenTween/Setting/SettingCommon.cs | 10 +- OpenTween/Setting/SettingLocal.cs | 4 +- OpenTween/Setting/SettingManager.cs | 2 +- OpenTween/ShortUrl.cs | 2 +- .../Services/MetaThumbnailService.cs | 2 +- OpenTween/ToolStripAPIGauge.cs | 4 +- OpenTween/Tween.cs | 108 +++++++++--------- OpenTween/TweetDetailsView.cs | 16 +-- OpenTween/TweetFormatter.cs | 2 +- OpenTween/TweetThumbnail.cs | 2 +- OpenTween/Twitter.cs | 18 +-- 38 files changed, 156 insertions(+), 152 deletions(-) diff --git a/OpenTween/Api/BitlyApi.cs b/OpenTween/Api/BitlyApi.cs index 92b8ccb9e..133d49461 100644 --- a/OpenTween/Api/BitlyApi.cs +++ b/OpenTween/Api/BitlyApi.cs @@ -64,7 +64,7 @@ public async Task ShortenAsync(Uri srcUri, string? domain = null) ["longUrl"] = srcUri.OriginalString, }; - if (!string.IsNullOrEmpty(domain)) + if (!MyCommon.IsNullOrEmpty(domain)) query["domain"] = domain; var uri = new Uri("/v3/shorten", UriKind.Relative); @@ -138,7 +138,7 @@ private string ParseOAuthCredential(byte[] responseBytes) private IEnumerable> CreateAccessTokenParams() { - if (string.IsNullOrEmpty(this.EndUserAccessToken)) + if (MyCommon.IsNullOrEmpty(this.EndUserAccessToken)) { return new[] { diff --git a/OpenTween/Api/MicrosoftTranslatorApi.cs b/OpenTween/Api/MicrosoftTranslatorApi.cs index 51e8abb21..b55835eed 100644 --- a/OpenTween/Api/MicrosoftTranslatorApi.cs +++ b/OpenTween/Api/MicrosoftTranslatorApi.cs @@ -97,7 +97,7 @@ await this.UpdateAccessTokenIfExpired() public async Task UpdateAccessTokenIfExpired() { - if (!string.IsNullOrEmpty(this.AccessToken) && this.RefreshAccessTokenAt > DateTimeUtc.Now) + if (!MyCommon.IsNullOrEmpty(this.AccessToken) && this.RefreshAccessTokenAt > DateTimeUtc.Now) return; var (accessToken, expiresIn) = await this.GetAccessTokenAsync() diff --git a/OpenTween/Api/TwitterApi.cs b/OpenTween/Api/TwitterApi.cs index e81279858..f651b8a28 100644 --- a/OpenTween/Api/TwitterApi.cs +++ b/OpenTween/Api/TwitterApi.cs @@ -775,9 +775,9 @@ public TwitterStreamObservable UserStreams(string? replies = null, string? track var endpoint = new Uri("https://userstream.twitter.com/1.1/user.json"); var param = new Dictionary(); - if (!string.IsNullOrEmpty(replies)) + if (!MyCommon.IsNullOrEmpty(replies)) param["replies"] = replies; - if (!string.IsNullOrEmpty(track)) + if (!MyCommon.IsNullOrEmpty(track)) param["track"] = track; Task openStream() diff --git a/OpenTween/Api/TwitterApiStatus.cs b/OpenTween/Api/TwitterApiStatus.cs index c26815f1e..564754124 100644 --- a/OpenTween/Api/TwitterApiStatus.cs +++ b/OpenTween/Api/TwitterApiStatus.cs @@ -80,7 +80,7 @@ public void Reset() return null; // たまに出てくる空文字列は無視する - if (string.IsNullOrEmpty(header[headerName])) + if (MyCommon.IsNullOrEmpty(header[headerName])) return null; switch (header[headerName]) diff --git a/OpenTween/Api/TwitterStreamObservable.cs b/OpenTween/Api/TwitterStreamObservable.cs index a7e945a18..d9c83fb50 100644 --- a/OpenTween/Api/TwitterStreamObservable.cs +++ b/OpenTween/Api/TwitterStreamObservable.cs @@ -79,7 +79,7 @@ private async void StreamLoop(IObserver observer, Cancell public static ITwitterStreamMessage ParseLine(string line) { - if (string.IsNullOrEmpty(line)) + if (MyCommon.IsNullOrEmpty(line)) return new StreamMessageKeepAlive(); if (line.First() != '{' || line.Last() != '}') diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index 13f93edf1..70838a62f 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -284,7 +284,7 @@ public void ApplyNetworkSettings() var pinPageUrl = TwitterApiConnection.GetAuthorizeUri(requestToken); var pin = AuthDialog.DoAuth(this, pinPageUrl); - if (string.IsNullOrEmpty(pin)) + if (MyCommon.IsNullOrEmpty(pin)) return null; // キャンセルされた場合 var accessTokenResponse = await TwitterApiConnection.GetAccessTokenAsync(requestToken, pin); @@ -320,7 +320,7 @@ private void OpenUrl(string url) var path = this.ActionPanel.BrowserPathText.Text; try { - if (!string.IsNullOrEmpty(path)) + if (!MyCommon.IsNullOrEmpty(path)) { if (path.StartsWith("\"", StringComparison.Ordinal) && path.Length > 2 && path.IndexOf("\"", 2, StringComparison.Ordinal) > -1) { diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index f384c04d6..afd8f5eb5 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -284,7 +284,7 @@ public static CultureInfo GetPreferredCulture(CultureInfo culture) private static bool SetConfigDirectoryPath() { - if (StartupOptions.TryGetValue("configDir", out var configDir) && !string.IsNullOrEmpty(configDir)) + if (StartupOptions.TryGetValue("configDir", out var configDir) && !MyCommon.IsNullOrEmpty(configDir)) { // 起動オプション /configDir で設定ファイルの参照先を変更できます if (!Directory.Exists(configDir)) diff --git a/OpenTween/AtIdSupplement.cs b/OpenTween/AtIdSupplement.cs index 49116d676..032f35bbc 100644 --- a/OpenTween/AtIdSupplement.cs +++ b/OpenTween/AtIdSupplement.cs @@ -88,7 +88,7 @@ private void ButtonCancel_Click(object sender, EventArgs e) private void TextId_KeyDown(object sender, KeyEventArgs e) { - if (e.KeyCode == Keys.Back && string.IsNullOrEmpty(this.TextId.Text)) + if (e.KeyCode == Keys.Back && MyCommon.IsNullOrEmpty(this.TextId.Text)) { inputText = ""; isBack = true; @@ -102,7 +102,7 @@ private void TextId_KeyDown(object sender, KeyEventArgs e) } else if (e.Control && e.KeyCode == Keys.Delete) { - if (!string.IsNullOrEmpty(this.TextId.Text)) + if (!MyCommon.IsNullOrEmpty(this.TextId.Text)) { var idx = this.TextId.AutoCompleteCustomSource.IndexOf(this.TextId.Text); if (idx > -1) @@ -126,7 +126,7 @@ private void AtIdSupplement_Load(object sender, EventArgs e) private void AtIdSupplement_Shown(object sender, EventArgs e) { TextId.Text = startChar; - if (!string.IsNullOrEmpty(this.StartsWith)) + if (!MyCommon.IsNullOrEmpty(this.StartsWith)) { TextId.Text += this.StartsWith.Substring(0, this.StartsWith.Length); } diff --git a/OpenTween/Connection/Networking.cs b/OpenTween/Connection/Networking.cs index 78fb59a38..1ae37f0f1 100644 --- a/OpenTween/Connection/Networking.cs +++ b/OpenTween/Connection/Networking.cs @@ -124,7 +124,7 @@ public static void SetWebProxy(ProxyType proxyType, string proxyAddress, int pro break; case ProxyType.Specified: proxy = new WebProxy(proxyAddress, proxyPort); - if (!string.IsNullOrEmpty(proxyUser) || !string.IsNullOrEmpty(proxyPassword)) + if (!MyCommon.IsNullOrEmpty(proxyUser) || !MyCommon.IsNullOrEmpty(proxyPassword)) proxy.Credentials = new NetworkCredential(proxyUser, proxyPassword); break; case ProxyType.IE: diff --git a/OpenTween/Connection/OAuthUtility.cs b/OpenTween/Connection/OAuthUtility.cs index 885aa9eda..8d4510690 100644 --- a/OpenTween/Connection/OAuthUtility.cs +++ b/OpenTween/Connection/OAuthUtility.cs @@ -96,7 +96,7 @@ public static Dictionary GetOAuthParameter(string consumerKey, s ["oauth_nonce"] = NonceRandom.Next(123400, 9999999).ToString(), ["oauth_version"] = "1.0", }; - if (!string.IsNullOrEmpty(token)) + if (!MyCommon.IsNullOrEmpty(token)) parameter.Add("oauth_token", token); // トークンがあれば追加 return parameter; } @@ -121,7 +121,7 @@ public static string CreateSignature(string consumerSecret, string? tokenSecret, var signatureBase = string.Format("{0}&{1}&{2}", method, MyCommon.UrlEncode(url), MyCommon.UrlEncode(paramString)); // 署名鍵の文字列をコンシューマー秘密鍵とアクセストークン秘密鍵から生成(&区切り。アクセストークン秘密鍵なくても&残すこと) var key = MyCommon.UrlEncode(consumerSecret) + "&"; - if (!string.IsNullOrEmpty(tokenSecret)) + if (!MyCommon.IsNullOrEmpty(tokenSecret)) key += MyCommon.UrlEncode(tokenSecret); // 鍵生成&署名生成 using var hmac = new HMACSHA1(Encoding.ASCII.GetBytes(key)); diff --git a/OpenTween/Connection/TwitterPhoto.cs b/OpenTween/Connection/TwitterPhoto.cs index c22afceec..ee1350b3b 100644 --- a/OpenTween/Connection/TwitterPhoto.cs +++ b/OpenTween/Connection/TwitterPhoto.cs @@ -142,7 +142,7 @@ async Task UploadInternal(IMediaItem media, string? category) var mediaId = await this.tw.UploadMedia(media, category) .ConfigureAwait(false); - if (!string.IsNullOrEmpty(media.AltText)) + if (!MyCommon.IsNullOrEmpty(media.AltText)) { await this.tw.Api.MediaMetadataCreate(mediaId, media.AltText) .ConfigureAwait(false); diff --git a/OpenTween/EventViewerDialog.cs b/OpenTween/EventViewerDialog.cs index 2cab19549..bf572581a 100644 --- a/OpenTween/EventViewerDialog.cs +++ b/OpenTween/EventViewerDialog.cs @@ -131,7 +131,7 @@ private MyCommon.EVENTTYPE ParseEventTypeFromTag() private bool IsFilterMatch(Twitter.FormattedEvent x) { - if (!CheckBoxFilter.Checked || string.IsNullOrEmpty(TextBoxKeyword.Text)) + if (!CheckBoxFilter.Checked || MyCommon.IsNullOrEmpty(TextBoxKeyword.Text)) { return true; } diff --git a/OpenTween/FilterDialog.cs b/OpenTween/FilterDialog.cs index 82c6bcd05..a32303d65 100644 --- a/OpenTween/FilterDialog.cs +++ b/OpenTween/FilterDialog.cs @@ -667,7 +667,7 @@ private void ButtonOK_Click(object sender, EventArgs e) else { ft.FilterBody = bdy.Split(' ', ' ') - .Where(x => !string.IsNullOrEmpty(x)) + .Where(x => !MyCommon.IsNullOrEmpty(x)) .ToArray(); } @@ -699,7 +699,7 @@ private void ButtonOK_Click(object sender, EventArgs e) else { ft.ExFilterBody = bdy.Split(' ', ' ') - .Where(x => !string.IsNullOrEmpty(x)) + .Where(x => !MyCommon.IsNullOrEmpty(x)) .ToArray(); } @@ -755,7 +755,7 @@ private bool CheckMatchRule(out bool isBlank) isBlank = false; if (RadioAND.Checked) { - if (string.IsNullOrEmpty(UID.Text) && string.IsNullOrEmpty(MSG1.Text) && string.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false) + if (MyCommon.IsNullOrEmpty(UID.Text) && MyCommon.IsNullOrEmpty(MSG1.Text) && MyCommon.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false) { isBlank = true; return true; @@ -785,7 +785,7 @@ private bool CheckMatchRule(out bool isBlank) } else { - if (string.IsNullOrEmpty(MSG2.Text) && string.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false) + if (MyCommon.IsNullOrEmpty(MSG2.Text) && MyCommon.IsNullOrEmpty(TextSource.Text) && CheckRetweet.Checked == false) { isBlank = true; return true; @@ -812,7 +812,7 @@ private bool CheckExcludeRule(out bool isBlank) isBlank = false; if (RadioExAnd.Checked) { - if (string.IsNullOrEmpty(ExUID.Text) && string.IsNullOrEmpty(ExMSG1.Text) && string.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false) + if (MyCommon.IsNullOrEmpty(ExUID.Text) && MyCommon.IsNullOrEmpty(ExMSG1.Text) && MyCommon.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false) { isBlank = true; return true; @@ -842,7 +842,7 @@ private bool CheckExcludeRule(out bool isBlank) } else { - if (string.IsNullOrEmpty(ExMSG2.Text) && string.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false) + if (MyCommon.IsNullOrEmpty(ExMSG2.Text) && MyCommon.IsNullOrEmpty(TextExSource.Text) && CheckExRetweet.Checked == false) { isBlank = true; return true; @@ -971,7 +971,7 @@ private async void ButtonAddTab_Click(object sender, EventArgs e) tabName = inputName.TabName; tabType = inputName.Usage; } - if (!string.IsNullOrEmpty(tabName)) + if (!MyCommon.IsNullOrEmpty(tabName)) { //List対応 ListElement? list = null; diff --git a/OpenTween/Growl.cs b/OpenTween/Growl.cs index 21dcf8ab8..fe0f1047d 100644 --- a/OpenTween/Growl.cs +++ b/OpenTween/Growl.cs @@ -268,7 +268,7 @@ public void Notify(NotifyType notificationType, string id, string title, string }; object? n; - if (icon != null || !string.IsNullOrEmpty(url)) + if (icon != null || !MyCommon.IsNullOrEmpty(url)) { var gCore = _core!.GetType("Growl.CoreLibrary.Resource"); object? res; diff --git a/OpenTween/HashtagManage.cs b/OpenTween/HashtagManage.cs index 7a5b4192b..01d8b3367 100644 --- a/OpenTween/HashtagManage.cs +++ b/OpenTween/HashtagManage.cs @@ -125,14 +125,14 @@ private void UnSelectButton_Click(object sender, EventArgs e) private int GetIndexOf(ListBox.ObjectCollection list, string value) { - if (string.IsNullOrEmpty(value)) return -1; + if (MyCommon.IsNullOrEmpty(value)) return -1; var idx = 0; foreach (var l in list) { var src = (string)l; - if (string.IsNullOrEmpty(src)) + if (MyCommon.IsNullOrEmpty(src)) { idx += 1; continue; @@ -151,7 +151,7 @@ private int GetIndexOf(ListBox.ObjectCollection list, string value) public void AddHashToHistory(string hash, bool isIgnorePermanent) { hash = hash.Trim(); - if (!string.IsNullOrEmpty(hash)) + if (!MyCommon.IsNullOrEmpty(hash)) { if (isIgnorePermanent || !this.IsPermanent) { @@ -231,7 +231,7 @@ private void UseHashText_KeyPress(object sender, KeyPressEventArgs e) if (e.KeyChar == '#') { _hashSupl.ShowDialog(); - if (!string.IsNullOrEmpty(_hashSupl.inputText)) + if (!MyCommon.IsNullOrEmpty(_hashSupl.inputText)) { var fHalf = ""; var eHalf = ""; @@ -256,7 +256,7 @@ private void HistoryHashList_DoubleClick(object sender, EventArgs e) public void ToggleHash() { - if (string.IsNullOrEmpty(this.UseHash)) + if (MyCommon.IsNullOrEmpty(this.UseHash)) { if (this.HistoryHashList.Items.Count > 0) this.UseHash = this.HistoryHashList.Items[0].ToString(); @@ -344,7 +344,7 @@ private bool AdjustHashtags(ref string hashtag, bool isShowWarn) { //ハッシュタグの整形 hashtag = hashtag.Trim(); - if (string.IsNullOrEmpty(hashtag)) + if (MyCommon.IsNullOrEmpty(hashtag)) { if (isShowWarn) MessageBox.Show("emply hashtag.", "Hashtag warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); return false; @@ -382,7 +382,7 @@ private void OK_Button_Click(object sender, EventArgs e) hash += hs + " "; } hash = hash.Trim(); - if (!string.IsNullOrEmpty(hash)) + if (!MyCommon.IsNullOrEmpty(hash)) { this.AddHashToHistory(hash, true); this.IsPermanent = this.CheckPermanent.Checked; diff --git a/OpenTween/ImageListViewItem.cs b/OpenTween/ImageListViewItem.cs index 058409511..b109e174c 100644 --- a/OpenTween/ImageListViewItem.cs +++ b/OpenTween/ImageListViewItem.cs @@ -88,7 +88,7 @@ public Task GetImageAsync(bool force = false) private async Task GetImageAsyncInternal(bool force) { - if (string.IsNullOrEmpty(this.imageUrl) || this.imageCache == null) + if (MyCommon.IsNullOrEmpty(this.imageUrl) || this.imageCache == null) return; if (!force && this.imageReference.Target != null) diff --git a/OpenTween/ListManage.cs b/OpenTween/ListManage.cs index fbbe78d9e..60b86be22 100644 --- a/OpenTween/ListManage.cs +++ b/OpenTween/ListManage.cs @@ -136,7 +136,7 @@ private async void OKEditButton_Click(object sender, EventArgs e) { var listItem = (ListElement)this.ListsList.SelectedItem; - if (string.IsNullOrEmpty(this.NameTextBox.Text)) + if (MyCommon.IsNullOrEmpty(this.NameTextBox.Text)) { MessageBox.Show(Properties.Resources.ListManageOKButton1); return; @@ -322,7 +322,7 @@ private async void UserList_SelectedIndexChanged(object sender, EventArgs e) this.UserFollowerNum.Text = user.FollowersCount.ToString("#,###,##0"); this.UserPostsNum.Text = user.StatusesCount.ToString("#,###,##0"); this.UserProfile.Text = user.Description; - if (!string.IsNullOrEmpty(user.RecentPost)) + if (!MyCommon.IsNullOrEmpty(user.RecentPost)) { this.UserTweetDateTime.Text = user.PostCreatedAt.ToLocalTimeString("yy/MM/dd HH:mm"); this.UserTweet.Text = user.RecentPost; diff --git a/OpenTween/MediaSelector.cs b/OpenTween/MediaSelector.cs index 5eec3e017..570dabcf6 100644 --- a/OpenTween/MediaSelector.cs +++ b/OpenTween/MediaSelector.cs @@ -77,7 +77,7 @@ public IMediaUploadService? SelectedService get { var serviceName = this.ServiceName; - if (string.IsNullOrEmpty(serviceName)) + if (MyCommon.IsNullOrEmpty(serviceName)) return null; return this.pictureService.TryGetValue(serviceName, out var service) @@ -200,7 +200,7 @@ public bool HasUploadableService(string fileName, bool ignoreSize) /// private bool IsUploadable(string serviceName, string ext, long? size) { - if (!string.IsNullOrEmpty(serviceName)) + if (!MyCommon.IsNullOrEmpty(serviceName)) { var imageService = this.pictureService[serviceName]; if (imageService.CheckFileExtension(ext)) @@ -394,7 +394,7 @@ public bool TryGetSelectedMedia([NotNullWhen(true)] out string? imageService, [N private IMediaItem? CreateFileMediaItem(string path, bool noMsgBox) { - if (string.IsNullOrEmpty(path)) return null; + if (MyCommon.IsNullOrEmpty(path)) return null; try { @@ -491,7 +491,7 @@ private void ImageFromSelectedFile(int index, IMediaItem? item, bool noMsgBox) if (isSelectedPage) this.ClearImageSelectedPicture(); - if (item == null || string.IsNullOrEmpty(item.Path)) return; + if (item == null || MyCommon.IsNullOrEmpty(item.Path)) return; try { @@ -563,11 +563,11 @@ private string MakeAvailableServiceText(string ext, long fileSize) var text = string.Join(", ", ImageServiceCombo.Items.Cast() .Where(serviceName => - !string.IsNullOrEmpty(serviceName) && + !MyCommon.IsNullOrEmpty(serviceName) && this.pictureService[serviceName].CheckFileExtension(ext) && this.pictureService[serviceName].CheckFileSize(ext, fileSize))); - if (string.IsNullOrEmpty(text)) + if (MyCommon.IsNullOrEmpty(text)) return Properties.Resources.PostPictureWarn6; return text; @@ -631,7 +631,7 @@ private void SetImageServiceCombo() private void SelectImageServiceComboItem(string svc, int? index = null) { int idx; - if (string.IsNullOrEmpty(svc)) + if (MyCommon.IsNullOrEmpty(svc)) { idx = index ?? 0; } diff --git a/OpenTween/Models/MediaInfo.cs b/OpenTween/Models/MediaInfo.cs index 51fa8a584..2390e15d3 100644 --- a/OpenTween/Models/MediaInfo.cs +++ b/OpenTween/Models/MediaInfo.cs @@ -44,7 +44,7 @@ public MediaInfo(string url, string? altText, string? videoUrl) { this.Url = url; this.AltText = altText; - this.VideoUrl = !string.IsNullOrEmpty(videoUrl) ? videoUrl : null; + this.VideoUrl = !MyCommon.IsNullOrEmpty(videoUrl) ? videoUrl : null; } public override bool Equals(object? obj) diff --git a/OpenTween/Models/PostFilterRule.cs b/OpenTween/Models/PostFilterRule.cs index c8ad53ea4..2a1df9997 100644 --- a/OpenTween/Models/PostFilterRule.cs +++ b/OpenTween/Models/PostFilterRule.cs @@ -331,7 +331,7 @@ public void Compile() { var filterExprs = new List(); - if (useNameField && !string.IsNullOrEmpty(filterName)) + if (useNameField && !MyCommon.IsNullOrEmpty(filterName)) { filterExprs.Add(Expression.OrElse( this.MakeGenericFilter(postParam, "ScreenName", filterName, useRegex, caseSensitive, exactMatch: true), @@ -339,7 +339,7 @@ public void Compile() } foreach (var body in filterBody) { - if (string.IsNullOrEmpty(body)) + if (MyCommon.IsNullOrEmpty(body)) continue; Expression bodyExpr; @@ -378,7 +378,7 @@ public void Compile() filterExprs.Add(bodyExpr); } - if (!string.IsNullOrEmpty(filterSource)) + if (!MyCommon.IsNullOrEmpty(filterSource)) { if (filterByUrl) filterExprs.Add(this.MakeGenericFilter(postParam, "SourceHtml", filterSource, useRegex, caseSensitive)); @@ -544,7 +544,7 @@ protected virtual string MakeSummary() { if (this.UseNameField) { - if (!string.IsNullOrEmpty(this.FilterName)) + if (!MyCommon.IsNullOrEmpty(this.FilterName)) { fs.AppendFormat(Properties.Resources.SetFiltersText1, this.FilterName); } @@ -593,7 +593,7 @@ protected virtual string MakeSummary() { fs.Append("LambdaExp/"); } - if (!string.IsNullOrEmpty(this.FilterSource)) + if (!MyCommon.IsNullOrEmpty(this.FilterSource)) { fs.AppendFormat("Src…{0}/", this.FilterSource); } @@ -606,7 +606,7 @@ protected virtual string MakeSummary() fs.Append(Properties.Resources.SetFiltersText12); if (this.ExUseNameField) { - if (!string.IsNullOrEmpty(this.ExFilterName)) + if (!MyCommon.IsNullOrEmpty(this.ExFilterName)) { fs.AppendFormat(Properties.Resources.SetFiltersText1, this.ExFilterName); } @@ -655,7 +655,7 @@ protected virtual string MakeSummary() { fs.Append("LambdaExp/"); } - if (!string.IsNullOrEmpty(this.ExFilterSource)) + if (!MyCommon.IsNullOrEmpty(this.ExFilterSource)) { fs.AppendFormat("Src…{0}/", this.ExFilterSource); } @@ -691,18 +691,18 @@ protected virtual string MakeSummary() /// この振り分けルールにマッチ条件が含まれているかを返します /// public bool HasMatchConditions() - => !string.IsNullOrEmpty(this.FilterName) || - this.FilterBody.Any(x => !string.IsNullOrEmpty(x)) || - !string.IsNullOrEmpty(this.FilterSource) || + => !MyCommon.IsNullOrEmpty(this.FilterName) || + this.FilterBody.Any(x => !MyCommon.IsNullOrEmpty(x)) || + !MyCommon.IsNullOrEmpty(this.FilterSource) || this.FilterRt; /// /// この振り分けルールに除外条件が含まれているかを返します /// public bool HasExcludeConditions() - => !string.IsNullOrEmpty(this.ExFilterName) || - this.ExFilterBody.Any(x => !string.IsNullOrEmpty(x)) || - !string.IsNullOrEmpty(this.ExFilterSource) || + => !MyCommon.IsNullOrEmpty(this.ExFilterName) || + this.ExFilterBody.Any(x => !MyCommon.IsNullOrEmpty(x)) || + !MyCommon.IsNullOrEmpty(this.ExFilterSource) || this.ExFilterRt; public override bool Equals(object? obj) diff --git a/OpenTween/Models/PublicSearchTabModel.cs b/OpenTween/Models/PublicSearchTabModel.cs index 8e8fd8c29..e4c5dadbc 100644 --- a/OpenTween/Models/PublicSearchTabModel.cs +++ b/OpenTween/Models/PublicSearchTabModel.cs @@ -70,7 +70,7 @@ public PublicSearchTabModel(string tabName) : base(tabName) public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress) { - if (string.IsNullOrEmpty(this.SearchWords)) + if (MyCommon.IsNullOrEmpty(this.SearchWords)) return; bool read; diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index c6badd040..53a764a57 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -370,7 +370,7 @@ public int SubmitUpdate(out string soundFile, out PostClass[] notifyPosts, // 通知サウンドは TabClass.Notify の値に関わらず鳴らす // SettingCommon.PlaySound が false であれば TweenMain 側で無効化される - if (!string.IsNullOrEmpty(tab.SoundFile)) + if (!MyCommon.IsNullOrEmpty(tab.SoundFile)) { if (!this.notifyPriorityByTabType.TryGetValue(tab.TabType, out var notifyPriority)) notifyPriority = 0; diff --git a/OpenTween/Models/UserTimelineTabModel.cs b/OpenTween/Models/UserTimelineTabModel.cs index f658754ee..07110ca8a 100644 --- a/OpenTween/Models/UserTimelineTabModel.cs +++ b/OpenTween/Models/UserTimelineTabModel.cs @@ -51,7 +51,7 @@ public UserTimelineTabModel(string tabName, string screenName) public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress) { - if (string.IsNullOrEmpty(this.ScreenName)) + if (MyCommon.IsNullOrEmpty(this.ScreenName)) return; bool read; diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 22a624ca8..8f8d6ee99 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -51,6 +51,7 @@ using OpenTween.Api; using OpenTween.Models; using OpenTween.Setting; +using System.Diagnostics.CodeAnalysis; namespace OpenTween { @@ -535,7 +536,7 @@ public static void MoveArrayItem(int[] values, int idx_fr, int idx_to) public static string EncryptString(string str) { - if (string.IsNullOrEmpty(str)) return ""; + if (MyCommon.IsNullOrEmpty(str)) return ""; //文字列をバイト型配列にする var bytesIn = Encoding.UTF8.GetBytes(str); @@ -587,7 +588,7 @@ public static string EncryptString(string str) public static string DecryptString(string str) { - if (string.IsNullOrEmpty(str)) return ""; + if (MyCommon.IsNullOrEmpty(str)) return ""; //DESCryptoServiceProviderオブジェクトの作成 using var des = new DESCryptoServiceProvider(); @@ -994,5 +995,8 @@ public static string UrlEncode(string stringToEncode) } return sb.ToString(); } + + public static bool IsNullOrEmpty([NotNullWhen(false)] string? value) + => string.IsNullOrEmpty(value); } } diff --git a/OpenTween/NativeMethods.cs b/OpenTween/NativeMethods.cs index c318452a6..209824ff6 100644 --- a/OpenTween/NativeMethods.cs +++ b/OpenTween/NativeMethods.cs @@ -330,7 +330,7 @@ private static void RefreshProxySettings(string? strProxy) InternetProxyInfo ipi; // Filling in structure - if (!string.IsNullOrEmpty(strProxy)) + if (!MyCommon.IsNullOrEmpty(strProxy)) { ipi = new InternetProxyInfo { diff --git a/OpenTween/SearchWordDialog.cs b/OpenTween/SearchWordDialog.cs index 58df0005a..f8eab67f1 100644 --- a/OpenTween/SearchWordDialog.cs +++ b/OpenTween/SearchWordDialog.cs @@ -152,7 +152,7 @@ private void ActivateSelectedTabPage() private void buttonSearchTimeline_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(this.textSearchTimeline.Text)) + if (MyCommon.IsNullOrEmpty(this.textSearchTimeline.Text)) { this.DialogResult = DialogResult.Cancel; return; @@ -171,7 +171,7 @@ private void buttonSearchTimeline_Click(object sender, EventArgs e) private void buttonSearchTimelineNew_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(this.textSearchTimeline.Text)) + if (MyCommon.IsNullOrEmpty(this.textSearchTimeline.Text)) { this.DialogResult = DialogResult.Cancel; return; @@ -190,7 +190,7 @@ private void buttonSearchTimelineNew_Click(object sender, EventArgs e) private void buttonSearchPublic_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(this.textSearchPublic.Text)) + if (MyCommon.IsNullOrEmpty(this.textSearchPublic.Text)) { this.DialogResult = DialogResult.Cancel; return; diff --git a/OpenTween/Setting/Panel/CooperatePanel.cs b/OpenTween/Setting/Panel/CooperatePanel.cs index a4f9f3e83..1a9586948 100644 --- a/OpenTween/Setting/Panel/CooperatePanel.cs +++ b/OpenTween/Setting/Panel/CooperatePanel.cs @@ -71,7 +71,7 @@ public void SaveConfig(SettingCommon settingCommon) private void UserAppointUrlText_Validating(object sender, CancelEventArgs e) { - if (!UserAppointUrlText.Text.StartsWith("http", StringComparison.Ordinal) && !string.IsNullOrEmpty(UserAppointUrlText.Text)) + if (!UserAppointUrlText.Text.StartsWith("http", StringComparison.Ordinal) && !MyCommon.IsNullOrEmpty(UserAppointUrlText.Text)) { MessageBox.Show("Text Error:正しいURLではありません"); } diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index dd1f35921..e5d8dfa75 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -66,7 +66,7 @@ public string EncryptTokenSecret private string Encrypt(string password) { - if (string.IsNullOrEmpty(password)) password = ""; + if (MyCommon.IsNullOrEmpty(password)) password = ""; if (password.Length > 0) { try @@ -85,7 +85,7 @@ private string Encrypt(string password) } private string Decrypt(string password) { - if (string.IsNullOrEmpty(password)) password = ""; + if (MyCommon.IsNullOrEmpty(password)) password = ""; if (password.Length > 0) { try @@ -249,7 +249,7 @@ private string Decrypt(string password) [XmlIgnore] public Version? SkipUpdateVersion { - get => string.IsNullOrEmpty(this.SkipUpdateVersionStr) ? null : Version.Parse(this.SkipUpdateVersionStr); + get => MyCommon.IsNullOrEmpty(this.SkipUpdateVersionStr) ? null : Version.Parse(this.SkipUpdateVersionStr); set => this.SkipUpdateVersionStr = value == null ? "" : value.ToString(); } @@ -271,7 +271,7 @@ public string EncryptTokenSecret } private string Encrypt(string password) { - if (string.IsNullOrEmpty(password)) password = ""; + if (MyCommon.IsNullOrEmpty(password)) password = ""; if (password.Length > 0) { try @@ -290,7 +290,7 @@ private string Encrypt(string password) } private string Decrypt(string password) { - if (string.IsNullOrEmpty(password)) password = ""; + if (MyCommon.IsNullOrEmpty(password)) password = ""; if (password.Length > 0) { try diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index eb4a60807..2e9e6e7cd 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -276,7 +276,7 @@ public string EncryptProxyPassword get { var pwd = ProxyPassword; - if (string.IsNullOrEmpty(pwd)) pwd = ""; + if (MyCommon.IsNullOrEmpty(pwd)) pwd = ""; if (pwd.Length > 0) { try @@ -296,7 +296,7 @@ public string EncryptProxyPassword set { var pwd = value; - if (string.IsNullOrEmpty(pwd)) pwd = ""; + if (MyCommon.IsNullOrEmpty(pwd)) pwd = ""; if (pwd.Length > 0) { try diff --git a/OpenTween/Setting/SettingManager.cs b/OpenTween/Setting/SettingManager.cs index 7da155cb5..12ee07dd0 100644 --- a/OpenTween/Setting/SettingManager.cs +++ b/OpenTween/Setting/SettingManager.cs @@ -54,7 +54,7 @@ public static void LoadCommon() if (settings.UserAccounts == null || settings.UserAccounts.Count == 0) { settings.UserAccounts = new List(); - if (!string.IsNullOrEmpty(settings.UserName)) + if (!MyCommon.IsNullOrEmpty(settings.UserName)) { var account = new UserAccount { diff --git a/OpenTween/ShortUrl.cs b/OpenTween/ShortUrl.cs index be314dcfe..2f601214d 100644 --- a/OpenTween/ShortUrl.cs +++ b/OpenTween/ShortUrl.cs @@ -402,7 +402,7 @@ private async Task ShortenByBitlyAsync(Uri srcUri, string domain = "bit.ly" return srcUri; // OAuth2 アクセストークンまたは API キー (旧方式) のいずれも設定されていなければ短縮しない - if (string.IsNullOrEmpty(this.BitlyAccessToken) && (string.IsNullOrEmpty(this.BitlyId) || string.IsNullOrEmpty(this.BitlyKey))) + if (MyCommon.IsNullOrEmpty(this.BitlyAccessToken) && (MyCommon.IsNullOrEmpty(this.BitlyId) || MyCommon.IsNullOrEmpty(this.BitlyKey))) return srcUri; var bitly = new BitlyApi diff --git a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs index 14f908adc..d364f9a68 100644 --- a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs @@ -88,7 +88,7 @@ public MetaThumbnailService(HttpClient? http, string urlPattern, string[]? propN .ConfigureAwait(false); var thumbnailUrl = this.GetThumbnailUrl(content); - if (string.IsNullOrEmpty(thumbnailUrl)) return null; + if (MyCommon.IsNullOrEmpty(thumbnailUrl)) return null; return new ThumbnailInfo { diff --git a/OpenTween/ToolStripAPIGauge.cs b/OpenTween/ToolStripAPIGauge.cs index 992bf623c..8143ebcae 100644 --- a/OpenTween/ToolStripAPIGauge.cs +++ b/OpenTween/ToolStripAPIGauge.cs @@ -92,7 +92,7 @@ public string? ApiEndpoint get => this._ApiEndpoint; set { - if (string.IsNullOrEmpty(value)) + if (MyCommon.IsNullOrEmpty(value)) { // リセット this._ApiEndpoint = null; @@ -222,7 +222,7 @@ protected virtual void UpdateText() minuteText = Math.Ceiling(this.remainMinutes).ToString(); } - var endpointText = string.IsNullOrEmpty(this._ApiEndpoint) ? "unknown" : this._ApiEndpoint; + var endpointText = MyCommon.IsNullOrEmpty(this._ApiEndpoint) ? "unknown" : this._ApiEndpoint; var textFormat = "API {0}/{1}"; this.Text = string.Format(textFormat, remainCountText, maxCountText); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 6a2028315..db2a31f2d 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -874,7 +874,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.tw = new Twitter(this.twitterApi); //認証関連 - if (string.IsNullOrEmpty(SettingManager.Common.Token)) SettingManager.Common.UserName = ""; + if (MyCommon.IsNullOrEmpty(SettingManager.Common.Token)) SettingManager.Common.UserName = ""; tw.Initialize(SettingManager.Common.Token, SettingManager.Common.TokenSecret, SettingManager.Common.UserName, SettingManager.Common.UserId); _initial = true; @@ -885,14 +885,14 @@ private void TweenMain_Load(object sender, EventArgs e) var firstRun = false; //ユーザー名、パスワードが未設定なら設定画面を表示(初回起動時など) - if (string.IsNullOrEmpty(tw.Username)) + if (MyCommon.IsNullOrEmpty(tw.Username)) { saveRequired = true; firstRun = true; //設定せずにキャンセルされたか、設定されたが依然ユーザー名が未設定ならプログラム終了 if (ShowSettingDialog(showTaskbarIcon: true) != DialogResult.OK || - string.IsNullOrEmpty(tw.Username)) + MyCommon.IsNullOrEmpty(tw.Username)) { Application.Exit(); //強制終了 return; @@ -911,7 +911,7 @@ private void TweenMain_Load(object sender, EventArgs e) tw.RestrictFavCheck = SettingManager.Common.RestrictFavCheck; tw.ReadOwnPost = SettingManager.Common.ReadOwnPost; tw.TrackWord = SettingManager.Common.TrackWord; - TrackToolStripMenuItem.Checked = !string.IsNullOrEmpty(tw.TrackWord); + TrackToolStripMenuItem.Checked = !MyCommon.IsNullOrEmpty(tw.TrackWord); tw.AllAtReply = SettingManager.Common.AllAtReply; AllrepliesToolStripMenuItem.Checked = tw.AllAtReply; ShortUrl.Instance.DisableExpanding = !SettingManager.Common.TinyUrlResolve; @@ -953,7 +953,7 @@ private void TweenMain_Load(object sender, EventArgs e) SettingManager.Common.HashIsPermanent, SettingManager.Common.HashIsHead, SettingManager.Common.HashIsNotAddToAtReply); - if (!string.IsNullOrEmpty(HashMgr.UseHash) && HashMgr.IsPermanent) HashStripSplitButton.Text = HashMgr.UseHash; + if (!MyCommon.IsNullOrEmpty(HashMgr.UseHash) && HashMgr.IsPermanent) HashStripSplitButton.Text = HashMgr.UseHash; //アイコンリスト作成 this.IconCache = new ImageCache(); @@ -1838,7 +1838,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo nt = GrowlHelper.NotifyType.Notify; } var bText = sb.ToString(); - if (string.IsNullOrEmpty(bText)) return; + if (MyCommon.IsNullOrEmpty(bText)) return; var image = this.IconCache.TryGetFromCache(post.ImageUrl); gh.Notify(nt, post.StatusId.ToString(), title.ToString(), bText, image?.Image, post.ImageUrl); @@ -1897,7 +1897,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo title.AppendFormat(Properties.Resources.RefreshTimeline_NotifyText, addCount); } var bText = sb.ToString(); - if (string.IsNullOrEmpty(bText)) return; + if (MyCommon.IsNullOrEmpty(bText)) return; NotifyIcon1.BalloonTipTitle = title.ToString(); NotifyIcon1.BalloonTipText = bText; @@ -1908,7 +1908,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo } //サウンド再生 - if (!_initial && SettingManager.Common.PlaySound && !string.IsNullOrEmpty(soundFile)) + if (!_initial && SettingManager.Common.PlaySound && !MyCommon.IsNullOrEmpty(soundFile)) { try { @@ -2669,7 +2669,7 @@ await Task.Run(async () => if (ct.IsCancellationRequested) return; - if (!string.IsNullOrEmpty(errMsg) && + if (!MyCommon.IsNullOrEmpty(errMsg) && !errMsg.StartsWith("OK:", StringComparison.Ordinal) && !errMsg.StartsWith("Warn:", StringComparison.Ordinal)) { @@ -2706,7 +2706,7 @@ await Task.Run(async () => this._postTimestamps.RemoveAt(i); } - if (!this.HashMgr.IsPermanent && !string.IsNullOrEmpty(this.HashMgr.UseHash)) + if (!this.HashMgr.IsPermanent && !MyCommon.IsNullOrEmpty(this.HashMgr.UseHash)) { this.HashMgr.ClearHashtag(); this.HashStripSplitButton.Text = "#[-]"; @@ -3291,7 +3291,7 @@ private void ContextMenuOperate_Opening(object sender, CancelEventArgs e) { RepliedStatusOpenMenuItem.Enabled = true; } - if (!this.ExistCurrentPost || post == null || string.IsNullOrEmpty(post.RetweetedBy)) + if (!this.ExistCurrentPost || post == null || MyCommon.IsNullOrEmpty(post.RetweetedBy)) { MoveToRTHomeMenuItem.Enabled = false; } @@ -3864,7 +3864,7 @@ public void AddNewTabForSearch(string searchWord) //同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了 foreach (var tb in _statuses.GetTabsByType()) { - if (tb.SearchWords == searchWord && string.IsNullOrEmpty(tb.SearchLang)) + if (tb.SearchWords == searchWord && MyCommon.IsNullOrEmpty(tb.SearchLang)) { var tabIndex = this._statuses.Tabs.IndexOf(tb); this.ListTab.SelectedIndex = tabIndex; @@ -4076,7 +4076,7 @@ public bool AddNewTab(TabModel tab, bool startup) btn.TabIndex = 3; btn.Click += SearchButton_Click; - if (!string.IsNullOrEmpty(searchTab.SearchWords)) + if (!MyCommon.IsNullOrEmpty(searchTab.SearchWords)) { cmb.Items.Add(searchTab.SearchWords); cmb.Text = searchTab.SearchWords; @@ -4284,7 +4284,7 @@ private void ListTab_MouseMove(object sender, MouseEventArgs e) tn = this.CurrentTabName; } - if (string.IsNullOrEmpty(tn)) return; + if (MyCommon.IsNullOrEmpty(tn)) return; var tabIndex = this._statuses.Tabs.IndexOf(tn); if (tabIndex != -1) @@ -4404,7 +4404,7 @@ public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog, int offset, str var eHalf = ""; if (dialog.DialogResult == DialogResult.OK) { - if (!string.IsNullOrEmpty(dialog.inputText)) + if (!MyCommon.IsNullOrEmpty(dialog.inputText)) { if (selStart > 0) { @@ -4484,7 +4484,7 @@ private void StatusText_TextChanged(object sender, EventArgs e) this.StatusText.AccessibleDescription = string.Format(Properties.Resources.StatusText_AccessibleDescription, pLen); - if (string.IsNullOrEmpty(StatusText.Text)) + if (MyCommon.IsNullOrEmpty(StatusText.Text)) { this.inReplyTo = null; } @@ -4640,7 +4640,7 @@ private string FormatStatusText(string statusText) var footer = ""; var hashtag = this.HashMgr.UseHash; - if (!string.IsNullOrEmpty(hashtag) && !(this.HashMgr.IsNotAddToAtReply && this.inReplyTo != null)) + if (!MyCommon.IsNullOrEmpty(hashtag) && !(this.HashMgr.IsNotAddToAtReply && this.inReplyTo != null)) { if (HashMgr.IsHead) header = HashMgr.UseHash + " "; @@ -4655,7 +4655,7 @@ private string FormatStatusText(string statusText) // 推奨ステータスを使用する footer += this.recommendedStatusFooter; } - else if (!string.IsNullOrEmpty(SettingManager.Local.StatusText)) + else if (!MyCommon.IsNullOrEmpty(SettingManager.Local.StatusText)) { // テキストボックスに入力されている文字列を使用する footer += " " + SettingManager.Local.StatusText.Trim(); @@ -6484,7 +6484,7 @@ private void GoRelPost(bool forward) if (post.ScreenName == _anchorPost.ScreenName || post.RetweetedBy == _anchorPost.ScreenName || post.ScreenName == _anchorPost.RetweetedBy || - (!string.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == _anchorPost.RetweetedBy) || + (!MyCommon.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == _anchorPost.RetweetedBy) || _anchorPost.ReplyToList.Any(x => x.UserId == post.UserId) || _anchorPost.ReplyToList.Any(x => x.UserId == post.RetweetedByUserId) || post.ReplyToList.Any(x => x.UserId == _anchorPost.UserId) || @@ -7241,7 +7241,7 @@ public bool TabRename(string origTabName, [NotNullWhen(true)] out string? newTab newTabName = inputName.TabName; } this.TopMost = SettingManager.Common.AlwaysTop; - if (!string.IsNullOrEmpty(newTabName)) + if (!MyCommon.IsNullOrEmpty(newTabName)) { //新タブ名存在チェック if (this._statuses.ContainsTab(newTabName)) @@ -7344,7 +7344,7 @@ private void ListTab_DragDrop(object sender, DragEventArgs e) } //タブのないところにドロップ->最後尾へ移動 - if (string.IsNullOrEmpty(tn)) + if (MyCommon.IsNullOrEmpty(tn)) { var lastTab = this._statuses.Tabs.Last(); tn = lastTab.TabName; @@ -7420,7 +7420,7 @@ private void MakeReplyOrDirectStatus(bool isAuto = true, bool isReply = true, bo StatusText.Focus(); return; } - if (string.IsNullOrEmpty(StatusText.Text)) + if (MyCommon.IsNullOrEmpty(StatusText.Text)) { //空の場合 var inReplyToStatusId = post.RetweetedId ?? post.StatusId; @@ -7593,7 +7593,7 @@ private void MakeReplyOrDirectStatus(bool isAuto = true, bool isReply = true, bo ids += "@" + screenName + " "; } } - if (!string.IsNullOrEmpty(post.RetweetedBy)) + if (!MyCommon.IsNullOrEmpty(post.RetweetedBy)) { if (!ids.Contains("@" + post.RetweetedBy + " ") && post.RetweetedByUserId != tw.UserId) { @@ -7601,7 +7601,7 @@ private void MakeReplyOrDirectStatus(bool isAuto = true, bool isReply = true, bo } } if (ids.Length == 0) return; - if (string.IsNullOrEmpty(StatusText.Text)) + if (MyCommon.IsNullOrEmpty(StatusText.Text)) { //未入力の場合のみ返信先付加 var inReplyToStatusId = post.RetweetedId ?? post.StatusId; @@ -7709,7 +7709,7 @@ private void TimerRefreshIcon_Tick(object sender, EventArgs e) private void ContextMenuTabProperty_Opening(object sender, CancelEventArgs e) { //右クリックの場合はタブ名が設定済。アプリケーションキーの場合は現在のタブを対象とする - if (string.IsNullOrEmpty(_rclickTabName) || sender != ContextMenuTabProperty) + if (MyCommon.IsNullOrEmpty(_rclickTabName) || sender != ContextMenuTabProperty) _rclickTabName = this.CurrentTabName; if (_statuses == null) return; @@ -7793,7 +7793,7 @@ private void ProtectTabMenuItem_Click(object sender, EventArgs e) this.DeleteTabMenuItem.Enabled = !checkState; this.DeleteTbMenuItem.Enabled = !checkState; - if (string.IsNullOrEmpty(_rclickTabName)) return; + if (MyCommon.IsNullOrEmpty(_rclickTabName)) return; _statuses.Tabs[_rclickTabName].Protected = checkState; SaveConfigsTabs(); @@ -7804,7 +7804,7 @@ private void UreadManageMenuItem_Click(object sender, EventArgs e) UreadManageMenuItem.Checked = ((ToolStripMenuItem)sender).Checked; this.UnreadMngTbMenuItem.Checked = UreadManageMenuItem.Checked; - if (string.IsNullOrEmpty(_rclickTabName)) return; + if (MyCommon.IsNullOrEmpty(_rclickTabName)) return; ChangeTabUnreadManage(_rclickTabName, UreadManageMenuItem.Checked); SaveConfigsTabs(); @@ -7844,7 +7844,7 @@ private void NotifyDispMenuItem_Click(object sender, EventArgs e) NotifyDispMenuItem.Checked = ((ToolStripMenuItem)sender).Checked; this.NotifyTbMenuItem.Checked = NotifyDispMenuItem.Checked; - if (string.IsNullOrEmpty(_rclickTabName)) return; + if (MyCommon.IsNullOrEmpty(_rclickTabName)) return; _statuses.Tabs[_rclickTabName].Notify = NotifyDispMenuItem.Checked; @@ -7853,7 +7853,7 @@ private void NotifyDispMenuItem_Click(object sender, EventArgs e) private void SoundFileComboBox_SelectedIndexChanged(object sender, EventArgs e) { - if (soundfileListup || string.IsNullOrEmpty(_rclickTabName)) return; + if (soundfileListup || MyCommon.IsNullOrEmpty(_rclickTabName)) return; _statuses.Tabs[_rclickTabName].SoundFile = (string)((ToolStripComboBox)sender).SelectedItem; @@ -7862,7 +7862,7 @@ private void SoundFileComboBox_SelectedIndexChanged(object sender, EventArgs e) private void DeleteTabMenuItem_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(_rclickTabName) || sender == this.DeleteTbMenuItem) + if (MyCommon.IsNullOrEmpty(_rclickTabName) || sender == this.DeleteTbMenuItem) _rclickTabName = this.CurrentTabName; RemoveSpecifiedTab(_rclickTabName, true); @@ -7871,7 +7871,7 @@ private void DeleteTabMenuItem_Click(object sender, EventArgs e) private void FilterEditMenuItem_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(_rclickTabName)) _rclickTabName = _statuses.HomeTab.TabName; + if (MyCommon.IsNullOrEmpty(_rclickTabName)) _rclickTabName = _statuses.HomeTab.TabName; using (var fltDialog = new FilterDialog()) { @@ -7899,7 +7899,7 @@ private async void AddTabMenuItem_Click(object sender, EventArgs e) tabUsage = inputName.Usage; } this.TopMost = SettingManager.Common.AlwaysTop; - if (!string.IsNullOrEmpty(tabName)) + if (!MyCommon.IsNullOrEmpty(tabName)) { //List対応 ListElement? list = null; @@ -8221,7 +8221,7 @@ private bool SelectTab([NotNullWhen(true)] out FilterTabModel? tab) tabName = inputName.TabName; } this.TopMost = SettingManager.Common.AlwaysTop; - if (!string.IsNullOrEmpty(tabName)) + if (!MyCommon.IsNullOrEmpty(tabName)) { var newTab = new FilterTabModel(tabName); if (!_statuses.AddTab(newTab) || !AddNewTab(newTab, startup: false)) @@ -8336,7 +8336,7 @@ private async void OpenURLMenuItem_Click(object sender, EventArgs e) var href = linkElm.GetAttribute("href"); var linkedText = linkElm.InnerText; - if (string.IsNullOrEmpty(displayUrl)) + if (MyCommon.IsNullOrEmpty(displayUrl)) displayUrl = href; links.Add(new OpenUrlItem(linkedText, displayUrl, href)); @@ -8379,7 +8379,7 @@ private async void OpenURLMenuItem_Click(object sender, EventArgs e) private void ClearTabMenuItem_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(_rclickTabName)) return; + if (MyCommon.IsNullOrEmpty(_rclickTabName)) return; ClearTab(_rclickTabName, true); } @@ -8639,11 +8639,11 @@ internal void CheckReplyTo(string StatusText) HashSupl.AddItem("#" + hm.Result("$3")); } } - if (!string.IsNullOrEmpty(HashMgr.UseHash) && !hstr.Contains(HashMgr.UseHash + " ")) + if (!MyCommon.IsNullOrEmpty(HashMgr.UseHash) && !hstr.Contains(HashMgr.UseHash + " ")) { hstr += HashMgr.UseHash; } - if (!string.IsNullOrEmpty(hstr)) HashMgr.AddHashToHistory(hstr.Trim(), false); + if (!MyCommon.IsNullOrEmpty(hstr)) HashMgr.AddHashToHistory(hstr.Trim(), false); // 本当にリプライ先指定すべきかどうかの判定 m = Regex.Matches(StatusText, "(^|[ -/:-@[-^`{-~])(?@[a-zA-Z0-9_]+)"); @@ -8867,8 +8867,8 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) if (Converter_Type == MyCommon.UrlConverter.Bitly || Converter_Type == MyCommon.UrlConverter.Jmp) { // OAuth2 アクセストークンまたは API キー (旧方式) のいずれも設定されていなければ短縮しない - if (string.IsNullOrEmpty(SettingManager.Common.BitlyAccessToken) && - (string.IsNullOrEmpty(SettingManager.Common.BilyUser) || string.IsNullOrEmpty(SettingManager.Common.BitlyPwd))) + if (MyCommon.IsNullOrEmpty(SettingManager.Common.BitlyAccessToken) && + (MyCommon.IsNullOrEmpty(SettingManager.Common.BilyUser) || MyCommon.IsNullOrEmpty(SettingManager.Common.BitlyPwd))) { MessageBox.Show(this, Properties.Resources.UrlConvert_BitlyAuthRequired, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; @@ -8921,7 +8921,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) return true; } - if (!string.IsNullOrEmpty(result)) + if (!MyCommon.IsNullOrEmpty(result)) { var undotmp = new urlUndo(); @@ -9006,7 +9006,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) continue; } - if (!string.IsNullOrEmpty(result)) + if (!MyCommon.IsNullOrEmpty(result)) { // 短縮 URL が生成されるまでの間に投稿欄から元の URL が削除されていたら中断する var origUrlIndex = this.StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal); @@ -9452,7 +9452,7 @@ public Task OpenUriInBrowserAsync(string UriString) try { var configBrowserPath = SettingManager.Local.BrowserPath; - if (!string.IsNullOrEmpty(configBrowserPath)) + if (!MyCommon.IsNullOrEmpty(configBrowserPath)) { if (configBrowserPath.StartsWith("\"", StringComparison.Ordinal) && configBrowserPath.Length > 2 && configBrowserPath.IndexOf("\"", 2, StringComparison.Ordinal) > -1) { @@ -9879,7 +9879,7 @@ private void TweenMain_Deactivate(object sender, EventArgs e) private void TabRenameMenuItem_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(_rclickTabName)) return; + if (MyCommon.IsNullOrEmpty(_rclickTabName)) return; _ = TabRename(_rclickTabName, out _); } @@ -10259,7 +10259,7 @@ private async void SearchButton_Click(object sender, EventArgs e) tb.SearchWords = cmb.Text; tb.SearchLang = cmbLang.Text; - if (string.IsNullOrEmpty(cmb.Text)) + if (MyCommon.IsNullOrEmpty(cmb.Text)) { listView.Focus(); SaveConfigsTabs(); @@ -10440,7 +10440,7 @@ private void HashManageMenuItem_Click(object sender, EventArgs e) } this.TopMost = SettingManager.Common.AlwaysTop; if (rslt == DialogResult.Cancel) return; - if (!string.IsNullOrEmpty(HashMgr.UseHash)) + if (!MyCommon.IsNullOrEmpty(HashMgr.UseHash)) { HashStripSplitButton.Text = HashMgr.UseHash; HashTogglePullDownMenuItem.Checked = true; @@ -10460,7 +10460,7 @@ private void HashManageMenuItem_Click(object sender, EventArgs e) private void HashToggleMenuItem_Click(object sender, EventArgs e) { HashMgr.ToggleHash(); - if (!string.IsNullOrEmpty(HashMgr.UseHash)) + if (!MyCommon.IsNullOrEmpty(HashMgr.UseHash)) { HashStripSplitButton.Text = HashMgr.UseHash; HashToggleMenuItem.Checked = true; @@ -10577,7 +10577,7 @@ private void MenuItemOperate_DropDownOpening(object sender, EventArgs e) { OpenRepSourceOpMenuItem.Enabled = true; } - if (!this.ExistCurrentPost || post == null || string.IsNullOrEmpty(post.RetweetedBy)) + if (!this.ExistCurrentPost || post == null || MyCommon.IsNullOrEmpty(post.RetweetedBy)) { OpenRterHomeMenuItem.Enabled = false; } @@ -11204,13 +11204,13 @@ private void NotifyEvent(Twitter.FormattedEvent ev) title.Append(" ["); title.Append(ev.Event.ToUpper(CultureInfo.CurrentCulture)); title.Append("] by "); - if (!string.IsNullOrEmpty(ev.Username)) + if (!MyCommon.IsNullOrEmpty(ev.Username)) { title.Append(ev.Username); } string text; - if (!string.IsNullOrEmpty(ev.Target)) + if (!MyCommon.IsNullOrEmpty(ev.Target)) text = ev.Target; else text = " "; @@ -11231,7 +11231,7 @@ private void NotifyEvent(Twitter.FormattedEvent ev) //サウンド再生 var snd = SettingManager.Common.EventSoundFile; - if (!_initial && SettingManager.Common.PlaySound && !string.IsNullOrEmpty(snd)) + if (!_initial && SettingManager.Common.PlaySound && !MyCommon.IsNullOrEmpty(snd)) { if ((ev.Eventtype & SettingManager.Common.EventNotifyFlag) != 0 && IsMyEventNotityAsEventType(ev)) { @@ -11292,7 +11292,7 @@ private void TrackToolStripMenuItem_Click(object sender, EventArgs e) { tw.TrackWord = inputTrack; this.MarkSettingCommonModified(); - TrackToolStripMenuItem.Checked = !string.IsNullOrEmpty(inputTrack); + TrackToolStripMenuItem.Checked = !MyCommon.IsNullOrEmpty(inputTrack); tw.ReconnectUserStream(); } } @@ -11379,7 +11379,7 @@ private string GetUserIdFromCurPostOrInput(string caption) inputName.TabName = id; if (inputName.ShowDialog() == DialogResult.OK && - !string.IsNullOrEmpty(inputName.TabName.Trim())) + !MyCommon.IsNullOrEmpty(inputName.TabName.Trim())) { id = inputName.TabName.Trim(); } @@ -11393,7 +11393,7 @@ private string GetUserIdFromCurPostOrInput(string caption) private async void UserTimelineToolStripMenuItem_Click(object sender, EventArgs e) { var id = GetUserIdFromCurPostOrInput("Show UserTimeline"); - if (!string.IsNullOrEmpty(id)) + if (!MyCommon.IsNullOrEmpty(id)) { await this.AddNewTabForUserTimeline(id); } @@ -11582,7 +11582,7 @@ private void LockListSortToolStripMenuItem_Click(object sender, EventArgs e) private void tweetDetailsView_StatusChanged(object sender, TweetDetailsViewStatusChengedEventArgs e) { - if (!string.IsNullOrEmpty(e.StatusText)) + if (!MyCommon.IsNullOrEmpty(e.StatusText)) { this.StatusLabelUrl.Text = e.StatusText; } diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 1b56aa35f..b005bcbe5 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -233,7 +233,7 @@ public HtmlElement[] GetLinkElements() private async Task SetUserPictureAsync(string imageUrl, bool force = false) { - if (string.IsNullOrEmpty(imageUrl)) + if (MyCommon.IsNullOrEmpty(imageUrl)) return; if (this.IconCache == null) @@ -364,7 +364,7 @@ public async Task DoTranslation() private async Task DoTranslation(string str) { - if (string.IsNullOrEmpty(str)) + if (MyCommon.IsNullOrEmpty(str)) return; var bing = new Bing(); @@ -504,7 +504,7 @@ private void PostBrowser_StatusTextChanged(object sender, EventArgs e) { this.RaiseStatusChanged(this.PostBrowser.StatusText.Replace("&", "&&")); } - if (string.IsNullOrEmpty(PostBrowser.StatusText)) + if (MyCommon.IsNullOrEmpty(PostBrowser.StatusText)) { this.RaiseStatusChanged(statusText: ""); } @@ -545,7 +545,7 @@ private void ContextMenuUserPicture_Opening(object sender, CancelEventArgs e) if (this.CurrentPost != null) { var name = this.CurrentPost.ImageUrl; - if (!string.IsNullOrEmpty(name)) + if (!MyCommon.IsNullOrEmpty(name)) { var idx = name.LastIndexOf('/'); if (idx != -1) @@ -692,7 +692,7 @@ private void SearchAtPostsDetailNameToolStripMenuItem_Click(object sender, Event private async void IconNameToolStripMenuItem_Click(object sender, EventArgs e) { var imageUrl = this.CurrentPost?.ImageUrl; - if (string.IsNullOrEmpty(imageUrl)) + if (MyCommon.IsNullOrEmpty(imageUrl)) return; await this.Owner.OpenUriInBrowserAsync(imageUrl.Remove(imageUrl.LastIndexOf("_normal", StringComparison.Ordinal), 7)); // "_normal".Length @@ -701,7 +701,7 @@ private async void IconNameToolStripMenuItem_Click(object sender, EventArgs e) private async void ReloadIconToolStripMenuItem_Click(object sender, EventArgs e) { var imageUrl = this.CurrentPost?.ImageUrl; - if (string.IsNullOrEmpty(imageUrl)) + if (MyCommon.IsNullOrEmpty(imageUrl)) return; await this.SetUserPictureAsync(imageUrl, force: true); @@ -710,7 +710,7 @@ private async void ReloadIconToolStripMenuItem_Click(object sender, EventArgs e) private void SaveIconPictureToolStripMenuItem_Click(object sender, EventArgs e) { var imageUrl = this.CurrentPost?.ImageUrl; - if (string.IsNullOrEmpty(imageUrl)) + if (MyCommon.IsNullOrEmpty(imageUrl)) return; var memoryImage = this.IconCache.TryGetFromCache(imageUrl); @@ -885,7 +885,7 @@ private void UrlCopyContextMenuItem_Click(object sender, EventArgs e) if (link.GetAttribute("href") == this._postBrowserStatusText) { var linkStr = link.GetAttribute("title"); - if (string.IsNullOrEmpty(linkStr)) + if (MyCommon.IsNullOrEmpty(linkStr)) linkStr = link.GetAttribute("href"); Clipboard.SetDataObject(linkStr, false, 5, 100); diff --git a/OpenTween/TweetFormatter.cs b/OpenTween/TweetFormatter.cs index 91865cb4a..a881dee44 100644 --- a/OpenTween/TweetFormatter.cs +++ b/OpenTween/TweetFormatter.cs @@ -168,7 +168,7 @@ private static string FormatEmojiEntity(string targetText, TwitterEntityEmoji en if (!SettingManager.Local.UseTwemoji) return t(e(targetText)); - if (string.IsNullOrEmpty(entity.Url)) + if (MyCommon.IsNullOrEmpty(entity.Url)) return ""; return "\"""; diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index 4f02655f6..b4df43f82 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -93,7 +93,7 @@ public async Task ShowThumbnailAsync(PostClass post, CancellationToken cancelTok loadTasks.Add(loadTask); var tooltipText = thumb.TooltipText; - if (!string.IsNullOrEmpty(tooltipText)) + if (!MyCommon.IsNullOrEmpty(tooltipText)) { this.toolTip.SetToolTip(picbox, tooltipText); picbox.AccessibleDescription = tooltipText; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index e184c27ed..64a46eccb 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -216,7 +216,7 @@ public async Task VerifyCredentialsAsync() public void Initialize(string token, string tokenSecret, string username, long userId) { //OAuth認証 - if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(tokenSecret) || string.IsNullOrEmpty(username)) + if (MyCommon.IsNullOrEmpty(token) || MyCommon.IsNullOrEmpty(tokenSecret) || MyCommon.IsNullOrEmpty(username)) { Twitter.AccountState = MyCommon.ACCOUNT_STATE.Invalid; } @@ -579,10 +579,10 @@ public async Task GetUserTimelineApi(bool read, string userName, UserTimelineTab var count = GetApiResultCount(MyCommon.WORKERTYPE.UserTimeline, more, false); TwitterStatus[] statuses; - if (string.IsNullOrEmpty(userName)) + if (MyCommon.IsNullOrEmpty(userName)) { var target = tab.ScreenName; - if (string.IsNullOrEmpty(target)) return; + if (MyCommon.IsNullOrEmpty(target)) return; userName = target; statuses = await this.Api.StatusesUserTimeline(userName, count) .ConfigureAwait(false); @@ -1397,14 +1397,14 @@ private string ReplaceTextFromApi(string text, TwitterEntities? entities, Twitte { foreach (var m in entities.Urls) { - if (!string.IsNullOrEmpty(m.DisplayUrl)) text = text.Replace(m.Url, m.DisplayUrl); + if (!MyCommon.IsNullOrEmpty(m.DisplayUrl)) text = text.Replace(m.Url, m.DisplayUrl); } } if (entities.Media != null) { foreach (var m in entities.Media) { - if (!string.IsNullOrEmpty(m.DisplayUrl)) text = text.Replace(m.Url, m.DisplayUrl); + if (!MyCommon.IsNullOrEmpty(m.DisplayUrl)) text = text.Replace(m.Url, m.DisplayUrl); } } } @@ -1435,7 +1435,7 @@ internal static string CreateAccessibleText(string text, TwitterEntities? entiti } } - if (!string.IsNullOrEmpty(entity.DisplayUrl)) + if (!MyCommon.IsNullOrEmpty(entity.DisplayUrl)) text = text.Replace(entity.Url, entity.DisplayUrl); } } @@ -1444,11 +1444,11 @@ internal static string CreateAccessibleText(string text, TwitterEntities? entiti { foreach (var entity in entities.Media) { - if (!string.IsNullOrEmpty(entity.AltText)) + if (!MyCommon.IsNullOrEmpty(entity.AltText)) { text = text.Replace(entity.Url, string.Format(Properties.Resources.ImageAltText, entity.AltText)); } - else if (!string.IsNullOrEmpty(entity.DisplayUrl)) + else if (!MyCommon.IsNullOrEmpty(entity.DisplayUrl)) { text = text.Replace(entity.Url, entity.DisplayUrl); } @@ -1670,7 +1670,7 @@ internal static string CreateHtmlAnchor(string text, TwitterEntities? entities, /// internal static (string SourceText, Uri? SourceUri) ParseSource(string? sourceHtml) { - if (string.IsNullOrEmpty(sourceHtml)) + if (MyCommon.IsNullOrEmpty(sourceHtml)) return ("", null); string sourceText; From 4f47742d8ccfd5fbb06c42ca7bb2b7651534084d Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 24 Sep 2019 04:22:59 +0900 Subject: [PATCH 006/402] =?UTF-8?q?event,=20delegate=20=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E3=81=99=E3=82=8Bnullable=E3=82=A2=E3=83=8E=E3=83=86=E3=83=BC?= =?UTF-8?q?=E3=82=B7=E3=83=A7=E3=83=B3=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Api/TwitterApiStatus.cs | 2 +- OpenTween/AppendSettingDialog.cs | 2 +- OpenTween/Connection/Networking.cs | 2 +- OpenTween/DetailsListView.cs | 4 ++-- OpenTween/Growl.cs | 2 +- OpenTween/HookGlobalHotkey.cs | 2 +- OpenTween/ImageListViewItem.cs | 2 +- OpenTween/LRUCacheDictionary.cs | 2 +- OpenTween/MediaSelector.cs | 10 +++++----- OpenTween/NotifyPropertyChangedBase.cs | 2 +- OpenTween/Setting/Panel/GetPeriodPanel.cs | 2 +- OpenTween/Thumbnail/Services/TonTwitterCom.cs | 4 ++-- OpenTween/TweetDetailsView.cs | 2 +- OpenTween/TweetThumbnail.cs | 6 +++--- OpenTween/Twitter.cs | 10 +++++----- 15 files changed, 27 insertions(+), 27 deletions(-) diff --git a/OpenTween/Api/TwitterApiStatus.cs b/OpenTween/Api/TwitterApiStatus.cs index 564754124..628265bd5 100644 --- a/OpenTween/Api/TwitterApiStatus.cs +++ b/OpenTween/Api/TwitterApiStatus.cs @@ -49,7 +49,7 @@ public class AccessLimitUpdatedEventArgs : EventArgs public AccessLimitUpdatedEventArgs(string? endpointName) => this.EndpointName = endpointName; } - public event EventHandler AccessLimitUpdated; + public event EventHandler? AccessLimitUpdated; public TwitterApiStatus() => this.AccessLimit = new EndpointLimits(this); diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index 70838a62f..b7dc66b47 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -48,7 +48,7 @@ namespace OpenTween { public partial class AppendSettingDialog : OTBaseForm { - public event EventHandler IntervalChanged; + public event EventHandler? IntervalChanged; internal Twitter tw = null!; internal TwitterApi twitterApi = null!; diff --git a/OpenTween/Connection/Networking.cs b/OpenTween/Connection/Networking.cs index 1ae37f0f1..a22d04bc3 100644 --- a/OpenTween/Connection/Networking.cs +++ b/OpenTween/Connection/Networking.cs @@ -84,7 +84,7 @@ private static bool IsWindows7 /// /// Webプロキシの設定が変更された場合に発生します /// - public static event EventHandler WebProxyChanged; + public static event EventHandler? WebProxyChanged; private static bool initialized = false; private static HttpClient globalHttpClient; diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index 9aae3df76..393d77511 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -44,8 +44,8 @@ public sealed class DetailsListView : ListView public ContextMenuStrip? ColumnHeaderContextMenuStrip { get; set; } - public event EventHandler VScrolled; - public event EventHandler HScrolled; + public event EventHandler? VScrolled; + public event EventHandler? HScrolled; public DetailsListView() { diff --git a/OpenTween/Growl.cs b/OpenTween/Growl.cs index fe0f1047d..70efc4d2f 100644 --- a/OpenTween/Growl.cs +++ b/OpenTween/Growl.cs @@ -69,7 +69,7 @@ public NotifyCallbackEventArgs(NotifyType notifyType, string statusId) } } - public event EventHandler NotifyClicked; + public event EventHandler? NotifyClicked; public string AppName { get; } diff --git a/OpenTween/HookGlobalHotkey.cs b/OpenTween/HookGlobalHotkey.cs index a53f51735..e7c36da3c 100644 --- a/OpenTween/HookGlobalHotkey.cs +++ b/OpenTween/HookGlobalHotkey.cs @@ -61,7 +61,7 @@ public enum ModKeys Win = 0x8, } - public event KeyEventHandler HotkeyPressed; + public event KeyEventHandler? HotkeyPressed; protected override void WndProc(ref Message m) { diff --git a/OpenTween/ImageListViewItem.cs b/OpenTween/ImageListViewItem.cs index b109e174c..65cfe65f2 100644 --- a/OpenTween/ImageListViewItem.cs +++ b/OpenTween/ImageListViewItem.cs @@ -51,7 +51,7 @@ public class ImageListViewItem : ListViewItem private readonly WeakReference imageReference = new WeakReference(null); private Task? imageTask = null; - public event EventHandler ImageDownloaded; + public event EventHandler? ImageDownloaded; public ImageListViewItem(string[] items) : this(items, null, null) diff --git a/OpenTween/LRUCacheDictionary.cs b/OpenTween/LRUCacheDictionary.cs index f5078fb01..5c8292050 100644 --- a/OpenTween/LRUCacheDictionary.cs +++ b/OpenTween/LRUCacheDictionary.cs @@ -58,7 +58,7 @@ public class CacheRemovedEventArgs : EventArgs public CacheRemovedEventArgs(KeyValuePair item) => this.Item = item; } - public event EventHandler CacheRemoved; + public event EventHandler? CacheRemoved; internal LinkedList> innerList; internal Dictionary>> innerDict; diff --git a/OpenTween/MediaSelector.cs b/OpenTween/MediaSelector.cs index 570dabcf6..f86474361 100644 --- a/OpenTween/MediaSelector.cs +++ b/OpenTween/MediaSelector.cs @@ -39,13 +39,13 @@ namespace OpenTween { public partial class MediaSelector : UserControl { - public event EventHandler BeginSelecting; - public event EventHandler EndSelecting; + public event EventHandler? BeginSelecting; + public event EventHandler? EndSelecting; - public event EventHandler FilePickDialogOpening; - public event EventHandler FilePickDialogClosed; + public event EventHandler? FilePickDialogOpening; + public event EventHandler? FilePickDialogClosed; - public event EventHandler SelectedServiceChanged; + public event EventHandler? SelectedServiceChanged; [Browsable(false)] [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] diff --git a/OpenTween/NotifyPropertyChangedBase.cs b/OpenTween/NotifyPropertyChangedBase.cs index 7cf65b4a5..f75ea7e39 100644 --- a/OpenTween/NotifyPropertyChangedBase.cs +++ b/OpenTween/NotifyPropertyChangedBase.cs @@ -36,7 +36,7 @@ namespace OpenTween /// public class NotifyPropertyChangedBase : INotifyPropertyChanged { - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; protected bool SetProperty(ref T field, T value, [CallerMemberName] string propertyName = "") { diff --git a/OpenTween/Setting/Panel/GetPeriodPanel.cs b/OpenTween/Setting/Panel/GetPeriodPanel.cs index 2c2cae5e8..fb0d496ee 100644 --- a/OpenTween/Setting/Panel/GetPeriodPanel.cs +++ b/OpenTween/Setting/Panel/GetPeriodPanel.cs @@ -39,7 +39,7 @@ namespace OpenTween.Setting.Panel { public partial class GetPeriodPanel : SettingPanelBase { - public event EventHandler IntervalChanged; + public event EventHandler? IntervalChanged; public GetPeriodPanel() => this.InitializeComponent(); diff --git a/OpenTween/Thumbnail/Services/TonTwitterCom.cs b/OpenTween/Thumbnail/Services/TonTwitterCom.cs index 265787615..5c45da457 100644 --- a/OpenTween/Thumbnail/Services/TonTwitterCom.cs +++ b/OpenTween/Thumbnail/Services/TonTwitterCom.cs @@ -40,7 +40,7 @@ namespace OpenTween.Thumbnail.Services /// class TonTwitterCom : IThumbnailService { - internal static Func GetApiConnection; + internal static Func? GetApiConnection; public override Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { @@ -68,7 +68,7 @@ public override Task LoadThumbnailImageAsync(HttpClient http, Cance { return Task.Run(async () => { - var apiConnection = TonTwitterCom.GetApiConnection(); + var apiConnection = TonTwitterCom.GetApiConnection!(); using var imageStream = await apiConnection.GetStreamAsync(new Uri(this.ThumbnailImageUrl), null) .ConfigureAwait(false); diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index b005bcbe5..ec33d6da6 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -66,7 +66,7 @@ public partial class TweetDetailsView : UserControl } /// ステータスバーに表示するテキストの変化を通知するイベント - public event EventHandler StatusChanged; + public event EventHandler? StatusChanged; /// 展開時の .StatusText を保持するフィールド private string _postBrowserStatusText = ""; diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index b4df43f82..0a255367f 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -46,9 +46,9 @@ public partial class TweetThumbnail : UserControl protected internal List pictureBox = new List(); protected MouseWheelMessageFilter filter = new MouseWheelMessageFilter(); - public event EventHandler ThumbnailLoading; - public event EventHandler ThumbnailDoubleClick; - public event EventHandler ThumbnailImageSearchClick; + public event EventHandler? ThumbnailLoading; + public event EventHandler? ThumbnailDoubleClick; + public event EventHandler? ThumbnailImageSearchClick; public ThumbnailInfo Thumbnail => (ThumbnailInfo)this.pictureBox[this.scrollBar.Value].Tag; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 64a46eccb..b9aa67a11 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1877,11 +1877,11 @@ int GetWeightFromCodepoint(int codepoint) public string TrackWord { get; set; } = ""; public bool AllAtReply { get; set; } = false; - public event EventHandler NewPostFromStream; - public event EventHandler UserStreamStarted; - public event EventHandler UserStreamStopped; - public event EventHandler PostDeleted; - public event EventHandler UserStreamEventReceived; + public event EventHandler? NewPostFromStream; + public event EventHandler? UserStreamStarted; + public event EventHandler? UserStreamStopped; + public event EventHandler? PostDeleted; + public event EventHandler? UserStreamEventReceived; private DateTimeUtc _lastUserstreamDataReceived; private StreamAutoConnector? userStreamConnector; From d8b055fd8cd2933f380e6f38b96753ffebe98ec0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 24 Sep 2019 04:23:27 +0900 Subject: [PATCH 007/402] =?UTF-8?q?=E9=9D=99=E7=9A=84=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E3=83=89=E3=81=AB=E9=96=A2=E3=81=99=E3=82=8B?= =?UTF-8?q?null=E5=8F=82=E7=85=A7=E3=81=AE=E8=AD=A6=E5=91=8A=E3=81=8C?= =?UTF-8?q?=E5=87=BA=E3=81=A6=E3=81=84=E3=82=8B=E7=AE=87=E6=89=80=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/PostClassTest.cs | 2 +- OpenTween/ApplicationEvents.cs | 2 +- OpenTween/MyCommon.cs | 2 +- OpenTween/Thumbnail/ThumbnailGenerator.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index 7f97dcfdc..63c115b1d 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -47,7 +47,7 @@ protected override PostClass RetweetSource private static Dictionary TestCases; - public PostClassTest() + static PostClassTest() { PostClassTest.TestCases = new Dictionary { diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index afd8f5eb5..9266ecfb7 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -55,7 +55,7 @@ internal class MyApplication /// /// 起動時に指定されたオプションを取得します /// - public static IDictionary StartupOptions { get; private set; } + public static IDictionary StartupOptions { get; private set; } = null!; /// /// アプリケーションのメイン エントリ ポイントです。 diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 8f8d6ee99..0094be029 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -59,7 +59,7 @@ public static class MyCommon { private static readonly object LockObj = new object(); public static bool _endingFlag; //終了フラグ - public static string settingPath; + public static string settingPath = null!; public enum IconSizes { diff --git a/OpenTween/Thumbnail/ThumbnailGenerator.cs b/OpenTween/Thumbnail/ThumbnailGenerator.cs index 9a207c36a..e84e4733c 100644 --- a/OpenTween/Thumbnail/ThumbnailGenerator.cs +++ b/OpenTween/Thumbnail/ThumbnailGenerator.cs @@ -38,7 +38,7 @@ class ThumbnailGenerator { public static List Services { get; protected set; } - internal static ImgAzyobuziNet ImgAzyobuziNetInstance { get; private set; } + internal static ImgAzyobuziNet ImgAzyobuziNetInstance { get; private set; } = null!; static ThumbnailGenerator() => ThumbnailGenerator.Services = new List(); From 7ed1036c10d3a95768b2d4f58af37030e3623065 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 25 Sep 2019 03:13:54 +0900 Subject: [PATCH 008/402] =?UTF-8?q?ColorizeList=E3=81=AE=E9=9D=9E=E5=90=8C?= =?UTF-8?q?=E6=9C=9F=E5=8C=96=E3=81=AB=E9=96=A2=E3=81=99=E3=82=8B=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E3=82=92=E5=B7=AE=E3=81=97=E6=88=BB=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: d2143257 ("発言一覧の選択位置が変化してから再描画するまで数msec待機する") --- OpenTween/DetailsListView.cs | 2 +- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 5 ++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index 393d77511..cf6f1ab55 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -108,7 +108,7 @@ public void ChangeItemForeColor(ListViewItem item, Color foreColor) public void ChangeItemFontAndColor(ListViewItem item, Color foreColor, Font fnt) { - if (item.ForeColor == foreColor && item.Font == fnt) + if (item.ForeColor == foreColor && item.Font.Equals(fnt)) return; item.ForeColor = foreColor; diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index edcf7faeb..3633b421a 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Ver 2.4.1-dev(2019/xx/xx) * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) + * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 ==== Ver 2.4.0(2019/09/24) * NEW: Twemoji 12.0.0 に対応しました diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index db2a31f2d..edfcc6502 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -366,7 +366,6 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ private readonly TimelineScheduler timelineScheduler = new TimelineScheduler(); private ThrottlingTimer RefreshThrottlingTimer = null!; - private ThrottlingTimer colorizeDebouncer = null!; private ThrottlingTimer selectionDebouncer = null!; private ThrottlingTimer saveConfigDebouncer = null!; @@ -1218,7 +1217,6 @@ private void TweenMain_Load(object sender, EventArgs e) var streamingRefreshInterval = TimeSpan.FromSeconds(SettingManager.Common.UserstreamPeriod); this.RefreshThrottlingTimer = ThrottlingTimer.Throttle(() => this.InvokeAsync(() => this.RefreshTimeline()), streamingRefreshInterval); - this.colorizeDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.ColorizeList()), TimeSpan.FromMilliseconds(100), leading: true); this.selectionDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.UpdateSelectedPost()), TimeSpan.FromMilliseconds(100), leading: true); this.saveConfigDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.SaveConfigsAll(ifModified: true)), TimeSpan.FromSeconds(1)); @@ -1955,7 +1953,7 @@ private void MyList_SelectedIndexChanged(object sender, EventArgs e) //キャッシュの書き換え ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色) - this.colorizeDebouncer.Call(); + this.ColorizeList(); this.selectionDebouncer.Call(); } @@ -2017,6 +2015,7 @@ private void ChangeItemStyleRead(bool Read, ListViewItem Item, PostClass Post, D } else { + DList.Update(); if (SettingManager.Common.UseUnreadStyle) DList.ChangeItemFontAndColor(Item, cl, fnt); else From 1dfe6e3b8f027e7697f775fad9efbe479748a842 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 25 Sep 2019 03:45:20 +0900 Subject: [PATCH 009/402] =?UTF-8?q?TimelineScheduler=E3=81=A7=E8=87=AA?= =?UTF-8?q?=E5=8B=95=E6=9B=B4=E6=96=B0=E3=81=AE=E7=84=A1=E5=8A=B9=E5=8C=96?= =?UTF-8?q?=E3=81=8C=E8=80=83=E6=85=AE=E3=81=95=E3=82=8C=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=81=AA=E3=81=84=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(thx=20@kamemory!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: c8b60400 ("タイムラインの定期更新に使用するタイマーの間隔を動的に制御する") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/TimelineScheduler.cs | 153 ++++++++++++++++++++++-------- OpenTween/Tween.cs | 15 +-- 3 files changed, 121 insertions(+), 48 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 3633b421a..a7b98aa38 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -3,6 +3,7 @@ ==== Ver 2.4.1-dev(2019/xx/xx) * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 + * FIX: 更新間隔を0秒に設定した場合に自動更新が停止されない不具合を修正 (thx @kamemory!) ==== Ver 2.4.0(2019/09/24) * NEW: Twemoji 12.0.0 に対応しました diff --git a/OpenTween/TimelineScheduler.cs b/OpenTween/TimelineScheduler.cs index 434d15183..8dcc16632 100644 --- a/OpenTween/TimelineScheduler.cs +++ b/OpenTween/TimelineScheduler.cs @@ -78,6 +78,30 @@ public bool Enabled public TimeSpan UpdateIntervalConfig { get; set; } = Timeout.InfiniteTimeSpan; public TimeSpan UpdateAfterSystemResume { get; set; } = Timeout.InfiniteTimeSpan; + public bool EnableUpdateHome + => this.UpdateIntervalHome != Timeout.InfiniteTimeSpan; + + public bool EnableUpdateMention + => this.UpdateIntervalMention != Timeout.InfiniteTimeSpan; + + public bool EnableUpdateDm + => this.UpdateIntervalDm != Timeout.InfiniteTimeSpan; + + public bool EnableUpdatePublicSearch + => this.UpdateIntervalPublicSearch != Timeout.InfiniteTimeSpan; + + public bool EnableUpdateUser + => this.UpdateIntervalUser != Timeout.InfiniteTimeSpan; + + public bool EnableUpdateList + => this.UpdateIntervalList != Timeout.InfiniteTimeSpan; + + public bool EnableUpdateConfig + => this.UpdateIntervalConfig != Timeout.InfiniteTimeSpan; + + public bool EnableUpdateSystemResume + => this.UpdateAfterSystemResume != Timeout.InfiniteTimeSpan; + public Func? UpdateHome; public Func? UpdateMention; public Func? UpdateDm; @@ -116,6 +140,9 @@ public void RefreshSchedule() public void SystemResumed() { + if (!this.EnableUpdateSystemResume) + return; + this.SystemResumedAt = DateTimeUtc.Now; this.systemResumeMode = true; this.RefreshSchedule(); @@ -145,33 +172,54 @@ private async Task TimerCallback_Normal() var round = TimeSpan.FromSeconds(1); // 1秒未満の差異であればまとめて実行する var tasks = UpdateTask.None; - var nextScheduledHome = this.LastUpdateHome + this.UpdateIntervalHome; - if (nextScheduledHome - now < round) - tasks |= UpdateTask.Home; + if (this.EnableUpdateHome) + { + var nextScheduledHome = this.LastUpdateHome + this.UpdateIntervalHome; + if (nextScheduledHome - now < round) + tasks |= UpdateTask.Home; + } - var nextScheduledMention = this.LastUpdateMention + this.UpdateIntervalMention; - if (nextScheduledMention - now < round) - tasks |= UpdateTask.Mention; + if (this.EnableUpdateMention) + { + var nextScheduledMention = this.LastUpdateMention + this.UpdateIntervalMention; + if (nextScheduledMention - now < round) + tasks |= UpdateTask.Mention; + } - var nextScheduledDm = this.LastUpdateDm + this.UpdateIntervalDm; - if (nextScheduledDm - now < round) - tasks |= UpdateTask.Dm; + if (this.EnableUpdateDm) + { + var nextScheduledDm = this.LastUpdateDm + this.UpdateIntervalDm; + if (nextScheduledDm - now < round) + tasks |= UpdateTask.Dm; + } - var nextScheduledPublicSearch = this.LastUpdatePublicSearch + this.UpdateIntervalPublicSearch; - if (nextScheduledPublicSearch - now < round) - tasks |= UpdateTask.PublicSearch; + if (this.EnableUpdatePublicSearch) + { + var nextScheduledPublicSearch = this.LastUpdatePublicSearch + this.UpdateIntervalPublicSearch; + if (nextScheduledPublicSearch - now < round) + tasks |= UpdateTask.PublicSearch; + } - var nextScheduledUser = this.LastUpdateUser + this.UpdateIntervalUser; - if (nextScheduledUser - now < round) - tasks |= UpdateTask.User; + if (this.EnableUpdateUser) + { + var nextScheduledUser = this.LastUpdateUser + this.UpdateIntervalUser; + if (nextScheduledUser - now < round) + tasks |= UpdateTask.User; + } - var nextScheduledList = this.LastUpdateList + this.UpdateIntervalList; - if (nextScheduledList - now < round) - tasks |= UpdateTask.List; + if (this.EnableUpdateList) + { + var nextScheduledList = this.LastUpdateList + this.UpdateIntervalList; + if (nextScheduledList - now < round) + tasks |= UpdateTask.List; + } - var nextScheduledConfig = this.LastUpdateConfig + this.UpdateIntervalConfig; - if (nextScheduledConfig - now < round) - tasks |= UpdateTask.Config; + if (this.EnableUpdateConfig) + { + var nextScheduledConfig = this.LastUpdateConfig + this.UpdateIntervalConfig; + if (nextScheduledConfig - now < round) + tasks |= UpdateTask.Config; + } await this.RunUpdateTasks(tasks, now).ConfigureAwait(false); } @@ -264,33 +312,54 @@ private TimeSpan NextTimerDelay() // 次に更新が予定される時刻を判定する var min = DateTimeUtc.MaxValue; - var nextScheduledHome = this.LastUpdateHome + this.UpdateIntervalHome; - if (nextScheduledHome < min) - min = nextScheduledHome; + if (this.EnableUpdateHome) + { + var nextScheduledHome = this.LastUpdateHome + this.UpdateIntervalHome; + if (nextScheduledHome < min) + min = nextScheduledHome; + } - var nextScheduledMention = this.LastUpdateMention + this.UpdateIntervalMention; - if (nextScheduledMention < min) - min = nextScheduledMention; + if (this.EnableUpdateMention) + { + var nextScheduledMention = this.LastUpdateMention + this.UpdateIntervalMention; + if (nextScheduledMention < min) + min = nextScheduledMention; + } - var nextScheduledDm = this.LastUpdateDm + this.UpdateIntervalDm; - if (nextScheduledDm < min) - min = nextScheduledDm; + if (this.EnableUpdateDm) + { + var nextScheduledDm = this.LastUpdateDm + this.UpdateIntervalDm; + if (nextScheduledDm < min) + min = nextScheduledDm; + } - var nextScheduledPublicSearch = this.LastUpdatePublicSearch + this.UpdateIntervalPublicSearch; - if (nextScheduledPublicSearch < min) - min = nextScheduledPublicSearch; + if (this.EnableUpdatePublicSearch) + { + var nextScheduledPublicSearch = this.LastUpdatePublicSearch + this.UpdateIntervalPublicSearch; + if (nextScheduledPublicSearch < min) + min = nextScheduledPublicSearch; + } - var nextScheduledUser = this.LastUpdateUser + this.UpdateIntervalUser; - if (nextScheduledUser < min) - min = nextScheduledUser; + if (this.EnableUpdateUser) + { + var nextScheduledUser = this.LastUpdateUser + this.UpdateIntervalUser; + if (nextScheduledUser < min) + min = nextScheduledUser; + } - var nextScheduledList = this.LastUpdateList + this.UpdateIntervalList; - if (nextScheduledList < min) - min = nextScheduledList; + if (this.EnableUpdateList) + { + var nextScheduledList = this.LastUpdateList + this.UpdateIntervalList; + if (nextScheduledList < min) + min = nextScheduledList; + } - var nextScheduledConfig = this.LastUpdateConfig + this.UpdateIntervalConfig; - if (nextScheduledConfig < min) - min = nextScheduledConfig; + if (this.EnableUpdateConfig) + { + var nextScheduledConfig = this.LastUpdateConfig + this.UpdateIntervalConfig; + if (nextScheduledConfig < min) + min = nextScheduledConfig; + } delay = min - DateTimeUtc.Now; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index edfcc6502..7756c6de6 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1388,12 +1388,15 @@ private void TimerInterval_Changed(object sender, IntervalChangedEventArgs e) private void RefreshTimelineScheduler() { - this.timelineScheduler.UpdateIntervalHome = TimeSpan.FromSeconds(SettingManager.Common.TimelinePeriod); - this.timelineScheduler.UpdateIntervalMention = TimeSpan.FromSeconds(SettingManager.Common.ReplyPeriod); - this.timelineScheduler.UpdateIntervalDm = TimeSpan.FromSeconds(SettingManager.Common.DMPeriod); - this.timelineScheduler.UpdateIntervalPublicSearch = TimeSpan.FromSeconds(SettingManager.Common.PubSearchPeriod); - this.timelineScheduler.UpdateIntervalUser = TimeSpan.FromSeconds(SettingManager.Common.UserTimelinePeriod); - this.timelineScheduler.UpdateIntervalList = TimeSpan.FromSeconds(SettingManager.Common.ListsPeriod); + static TimeSpan intervalSecondsOrDisabled(int seconds) + => seconds == 0 ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(seconds); + + this.timelineScheduler.UpdateIntervalHome = intervalSecondsOrDisabled(SettingManager.Common.TimelinePeriod); + this.timelineScheduler.UpdateIntervalMention = intervalSecondsOrDisabled(SettingManager.Common.ReplyPeriod); + this.timelineScheduler.UpdateIntervalDm = intervalSecondsOrDisabled(SettingManager.Common.DMPeriod); + this.timelineScheduler.UpdateIntervalPublicSearch = intervalSecondsOrDisabled(SettingManager.Common.PubSearchPeriod); + this.timelineScheduler.UpdateIntervalUser = intervalSecondsOrDisabled(SettingManager.Common.UserTimelinePeriod); + this.timelineScheduler.UpdateIntervalList = intervalSecondsOrDisabled(SettingManager.Common.ListsPeriod); this.timelineScheduler.UpdateIntervalConfig = TimeSpan.FromHours(6); this.timelineScheduler.UpdateAfterSystemResume = TimeSpan.FromSeconds(30); From b5530da8084336f615f230b161901e4a3f21538c Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 25 Sep 2019 03:52:28 +0900 Subject: [PATCH 010/402] =?UTF-8?q?OpenTween=20v2.4.1=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 10 +++++----- OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index f8ca9e457..f25f7a3cd 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.4.0.1")] +[assembly: AssemblyFileVersion("2.4.1.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 1fe63f499..e4820de42 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -652,7 +652,10 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Ver 2.4.1-dev(2019/xx/xx) + ///==== Ver 2.4.1(2019/09/25) + /// * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) + /// * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 + /// * FIX: 更新間隔を0秒に設定した場合に自動更新が停止されない不具合を修正 (thx @kamemory!) /// ///==== Ver 2.4.0(2019/09/24) /// * NEW: Twemoji 12.0.0 に対応しました @@ -661,10 +664,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * CHG: htn.to の短縮URLを展開する際に強制的にHTTPSを使用する /// * CHG: OpenTween内部で動作するタイマーの使用方法を見直し /// - 従来まで毎秒5回程度のタイマーイベントが常に発生していたのを、無操作時かつ発言一覧の更新がない間はほぼゼロになるよう改善しました - /// * FIX: Twemojiを有効にすると絵文字の後に余分な文字が表示される場合がある不具合を修正 - /// * FIX: Tumblrのサムネイル表示時にエラーが表示される場合がある不具合を修正 - /// * FIX: 発言内URLを開く(Ctrl+E)でURLにマルチバイト文字を含むとエラーが発生する場合がある不具合を修正 - /// * FIX: 英語版 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: Twemojiを有効 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index a7b98aa38..8728738b8 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Ver 2.4.1-dev(2019/xx/xx) +==== Ver 2.4.1(2019/09/25) * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 * FIX: 更新間隔を0秒に設定した場合に自動更新が停止されない不具合を修正 (thx @kamemory!) From 71e28b1da8425b662445262a29f7caee3adf8143 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 25 Sep 2019 03:54:16 +0900 Subject: [PATCH 011/402] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.4.2-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 5 +++-- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index f25f7a3cd..8c2cc7278 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.4.1.0")] +[assembly: AssemblyFileVersion("2.4.1.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index e4820de42..d1977c3c0 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -652,6 +652,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Ver 2.4.2-dev(2019/xx/xx) + /// ///==== Ver 2.4.1(2019/09/25) /// * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) /// * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 @@ -663,8 +665,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * CHG: DMの送信が完了したらDirectタブに送信したDMを即座に反映する /// * CHG: htn.to の短縮URLを展開する際に強制的にHTTPSを使用する /// * CHG: OpenTween内部で動作するタイマーの使用方法を見直し - /// - 従来まで毎秒5回程度のタイマーイベントが常に発生していたのを、無操作時かつ発言一覧の更新がない間はほぼゼロになるよう改善しました - /// * FIX: Twemojiを有効 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// - 従来まで毎秒5回程度のタイマーイベントが常に発生していたのを、無操作時かつ発言一覧の更新がない間はほ [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 8728738b8..266586a29 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Ver 2.4.2-dev(2019/xx/xx) + ==== Ver 2.4.1(2019/09/25) * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 diff --git a/appveyor.yml b/appveyor.yml index dde3d23cd..dd249e01b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.4.0.{build} +version: 2.4.1.{build} os: Visual Studio 2019 From 8ae04f8257c60257cbd35a8c898f3d0bfe6ccad2 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Oct 2019 19:02:34 +0900 Subject: [PATCH 012/402] =?UTF-8?q?TimerCallback=E5=86=85=E3=81=A7?= =?UTF-8?q?=E7=99=BA=E7=94=9F=E3=81=97=E3=81=9F=E4=BE=8B=E5=A4=96=E3=82=92?= =?UTF-8?q?=E5=BF=85=E3=81=9A=E3=83=8F=E3=83=B3=E3=83=89=E3=83=AB=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit タイマーでハンドルされない例外が生じると時々プロセスごと異常終了することがあるため --- OpenTween/ApplicationEvents.cs | 1 + OpenTween/AsyncTimer.cs | 61 +++++++++++++++++++ OpenTween/OpenTween.csproj | 1 + OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/ThrottlingTimer.cs | 6 +- .../Thumbnail/Services/ImgAzyobuziNet.cs | 8 +-- OpenTween/TimelineScheduler.cs | 6 +- 7 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 OpenTween/AsyncTimer.cs diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 9266ecfb7..3f2f6802b 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -102,6 +102,7 @@ static int Main(string[] args) }; Application.ThreadException += (s, e) => OnUnhandledException(e.Exception); AppDomain.CurrentDomain.UnhandledException += (s, e) => OnUnhandledException((Exception)e.ExceptionObject); + AsyncTimer.UnhandledException += (s, e) => OnUnhandledException(e.Exception); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); diff --git a/OpenTween/AsyncTimer.cs b/OpenTween/AsyncTimer.cs new file mode 100644 index 000000000..ed2b7a56e --- /dev/null +++ b/OpenTween/AsyncTimer.cs @@ -0,0 +1,61 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2019 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenTween +{ + public sealed class AsyncTimer : IDisposable + { + private readonly Func callback; + private readonly Timer timer; + + public static event EventHandler? UnhandledException; + + public AsyncTimer(Func callback) + { + this.callback = callback; + this.timer = new Timer(this.TimerCallback); + } + + private async void TimerCallback(object _) + { + try + { + await this.callback().ConfigureAwait(false); + } + catch (Exception ex) + { + UnhandledException?.Invoke(this, new ThreadExceptionEventArgs(ex)); + } + } + + public void Change(TimeSpan dueTime, TimeSpan period) + => this.timer.Change(dueTime, period); + + public void Dispose() + => this.timer.Dispose(); + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 961c361ac..e56f0f284 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -98,6 +98,7 @@ Code + Form diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 266586a29..1324f5466 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Ver 2.4.2-dev(2019/xx/xx) + * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 ==== Ver 2.4.1(2019/09/25) * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) diff --git a/OpenTween/ThrottlingTimer.cs b/OpenTween/ThrottlingTimer.cs index 3553c80cb..158222807 100644 --- a/OpenTween/ThrottlingTimer.cs +++ b/OpenTween/ThrottlingTimer.cs @@ -35,7 +35,7 @@ public class ThrottlingTimer : IDisposable private const int TIMER_DISABLED = 0; private const int TIMER_ENABLED = 1; - private readonly Timer throttlingTimer; + private readonly AsyncTimer throttlingTimer; private readonly Func timerCallback; private long lastCalledTick; @@ -68,7 +68,7 @@ public ThrottlingTimer(Func timerCallback, TimeSpan interval, TimeSpan max this.LastInvoked = DateTimeUtc.MinValue; this.InvokeLeading = leading; this.InvokeTrailing = trailing; - this.throttlingTimer = new Timer(this.Execute); + this.throttlingTimer = new AsyncTimer(this.Execute); } public void Call() @@ -89,7 +89,7 @@ public void Call() } } - private async void Execute(object _) + private async Task Execute() { var lastCalled = this.LastCalled; var lastInvoked = this.LastInvoked; diff --git a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs index 670bf2106..4804950fc 100644 --- a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs +++ b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs @@ -53,7 +53,7 @@ class ImgAzyobuziNet : IThumbnailService, IDisposable protected string? ApiBase; protected IEnumerable? UrlRegex = null; - protected Timer UpdateTimer; + protected AsyncTimer UpdateTimer; protected HttpClient http => this.localHttpClient ?? Networking.Http; @@ -74,7 +74,7 @@ public ImgAzyobuziNet(HttpClient? http) public ImgAzyobuziNet(HttpClient? http, bool autoupdate) { - this.UpdateTimer = new Timer(async _ => await this.LoadRegexAsync()); + this.UpdateTimer = new AsyncTimer(this.LoadRegexAsync); this.AutoUpdate = autoupdate; this.Enabled = true; @@ -109,10 +109,10 @@ public bool AutoUpdate public bool DisabledInDM { get; set; } protected void StartAutoUpdate() - => this.UpdateTimer.Change(0, 30 * 60 * 1000); // 30分おきに更新 + => this.UpdateTimer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(30)); // 30分おきに更新 protected void StopAutoUpdate() - => this.UpdateTimer.Change(Timeout.Infinite, Timeout.Infinite); + => this.UpdateTimer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan); public async Task LoadRegexAsync() { diff --git a/OpenTween/TimelineScheduler.cs b/OpenTween/TimelineScheduler.cs index 8dcc16632..2006800ef 100644 --- a/OpenTween/TimelineScheduler.cs +++ b/OpenTween/TimelineScheduler.cs @@ -30,7 +30,7 @@ namespace OpenTween { public class TimelineScheduler { - private readonly Timer timer; + private readonly AsyncTimer timer; private bool enabled = false; private bool systemResumeMode = false; @@ -125,7 +125,7 @@ private enum UpdateTask } public TimelineScheduler() - => this.timer = new Timer(_ => this.TimerCallback()); + => this.timer = new AsyncTimer(this.TimerCallback); public void RefreshSchedule() { @@ -148,7 +148,7 @@ public void SystemResumed() this.RefreshSchedule(); } - private async void TimerCallback() + private async Task TimerCallback() { try { From 71369aeebf05e3cabaa0653755565e7a6d52f3f1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 22 Oct 2019 05:27:21 +0900 Subject: [PATCH 013/402] =?UTF-8?q?ToolStripLabelHistory=E3=81=AB=E8=A4=87?= =?UTF-8?q?=E6=95=B0=E8=A1=8C=E3=81=AE=E3=83=86=E3=82=AD=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=82=92=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B=E3=81=A8=E7=B8=A6?= =?UTF-8?q?=E6=96=B9=E5=90=91=E3=81=AB=E5=BA=83=E3=81=8C=E3=82=8A=E6=88=BB?= =?UTF-8?q?=E3=82=89=E3=81=AA=E3=81=8F=E3=81=AA=E3=82=8B=E5=95=8F=E9=A1=8C?= =?UTF-8?q?=E3=82=92=E5=9B=9E=E9=81=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit objectName 付きの ObjectDisposedException のように改行文字を含むエラーメッセージを そのままステータスバーに表示した場合に起きる --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/ToolStripLabelHistory.cs | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 1324f5466..e62c00199 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Ver 2.4.2-dev(2019/xx/xx) * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 + * FIX: エラー発生時にステータスバーの縦幅が2行分に広がり戻らなくなる場合がある不具合を修正 ==== Ver 2.4.1(2019/09/25) * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) diff --git a/OpenTween/ToolStripLabelHistory.cs b/OpenTween/ToolStripLabelHistory.cs index 7aa8492d0..aeea24743 100644 --- a/OpenTween/ToolStripLabelHistory.cs +++ b/OpenTween/ToolStripLabelHistory.cs @@ -80,12 +80,13 @@ public override string Text get => base.Text; set { - _logs.AddLast(new LogEntry(DateTimeUtc.Now, value)); + var oneline = value.Replace("\n", " "); + _logs.AddLast(new LogEntry(DateTimeUtc.Now, oneline)); while (_logs.Count > MAXCNT) { _logs.RemoveFirst(); } - base.Text = value; + base.Text = oneline; } } From 4a421b52e58e44016b690eaf1b3c588ef6bb2efa Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 22 Oct 2019 16:30:22 +0900 Subject: [PATCH 014/402] =?UTF-8?q?=E9=81=B8=E6=8A=9E=E4=B8=AD=E3=81=AE?= =?UTF-8?q?=E3=82=BF=E3=83=96=E3=81=AE=E5=90=8D=E5=89=8D=E3=82=92=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=81=99=E3=82=8B=E3=81=A8SelectedTab=E3=81=AEgetter?= =?UTF-8?q?=E3=81=8C=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=AB=E3=81=AA=E3=82=8B?= =?UTF-8?q?=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/TabInformationTest.cs | 25 ++++++++++++++++++++ OpenTween/Models/TabInformations.cs | 4 ++++ OpenTween/Resources/ChangeLog.txt | 1 + 3 files changed, 30 insertions(+) diff --git a/OpenTween.Tests/Models/TabInformationTest.cs b/OpenTween.Tests/Models/TabInformationTest.cs index 67890420a..6b272a122 100644 --- a/OpenTween.Tests/Models/TabInformationTest.cs +++ b/OpenTween.Tests/Models/TabInformationTest.cs @@ -67,6 +67,31 @@ public void AddTab_DuplicateTest() Assert.False(ret); } + [Fact] + public void RenameTab_PositionTest() + { + var replyTab = this.tabinfo.Tabs["Reply"]; + Assert.Equal(1, this.tabinfo.Tabs.IndexOf(replyTab)); + + this.tabinfo.RenameTab("Reply", "Reply12345"); + + Assert.Equal("Reply12345", replyTab.TabName); + Assert.Equal(1, this.tabinfo.Tabs.IndexOf(replyTab)); + } + + [Fact] + public void RenameTab_SelectedTabTest() + { + var replyTab = this.tabinfo.Tabs["Reply"]; + + this.tabinfo.SelectTab("Reply"); + this.tabinfo.RenameTab("Reply", "Reply12345"); + + Assert.Equal("Reply12345", replyTab.TabName); + Assert.Equal("Reply12345", this.tabinfo.SelectedTabName); + Assert.Equal(replyTab, this.tabinfo.SelectedTab); + } + [Fact] public void SelectTab_Test() { diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index 53a764a57..1dc4f1fc2 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -670,6 +670,10 @@ public void RenameTab(string Original, string NewName) var tb = this.Tabs[Original]; this.tabs.RemoveAt(index); tb.TabName = NewName; + + if (this.SelectedTabName == Original) + this.SelectedTabName = NewName; + this.tabs.Insert(index, tb); } } diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index e62c00199..868dc8c74 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -3,6 +3,7 @@ ==== Ver 2.4.2-dev(2019/xx/xx) * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 * FIX: エラー発生時にステータスバーの縦幅が2行分に広がり戻らなくなる場合がある不具合を修正 + * FIX: 表示中のタブの名前を変更するとエラーが発生する不具合を修正 ==== Ver 2.4.1(2019/09/25) * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) From 24dbfbffb6640ddf3f1765c01c46d851c234364b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 23 Oct 2019 01:10:34 +0900 Subject: [PATCH 015/402] =?UTF-8?q?OpenTween=20v2.4.2=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 9 +++++---- OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 8c2cc7278..94a4815ef 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.4.1.1")] +[assembly: AssemblyFileVersion("2.4.2.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index d1977c3c0..1bd8b666a 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -652,7 +652,10 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Ver 2.4.2-dev(2019/xx/xx) + ///==== Ver 2.4.2(2019/10/23) + /// * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 + /// * FIX: エラー発生時にステータスバーの縦幅が2行分に広がり戻らなくなる場合がある不具合を修正 + /// * FIX: 表示中のタブの名前を変更するとエラーが発生する不具合を修正 /// ///==== Ver 2.4.1(2019/09/25) /// * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) @@ -663,9 +666,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * NEW: Twemoji 12.0.0 に対応しました /// - Unicode 12.0 で追加された絵文字が表示されるようになります /// * CHG: DMの送信が完了したらDirectタブに送信したDMを即座に反映する - /// * CHG: htn.to の短縮URLを展開する際に強制的にHTTPSを使用する - /// * CHG: OpenTween内部で動作するタイマーの使用方法を見直し - /// - 従来まで毎秒5回程度のタイマーイベントが常に発生していたのを、無操作時かつ発言一覧の更新がない間はほ [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 868dc8c74..f7c83dd8e 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Ver 2.4.2-dev(2019/xx/xx) +==== Ver 2.4.2(2019/10/23) * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 * FIX: エラー発生時にステータスバーの縦幅が2行分に広がり戻らなくなる場合がある不具合を修正 * FIX: 表示中のタブの名前を変更するとエラーが発生する不具合を修正 From 4d13df35349881946a944d957d73a90ae852b227 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 23 Oct 2019 01:13:07 +0900 Subject: [PATCH 016/402] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.4.3-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 5 +++-- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 94a4815ef..ee4a10aee 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.4.2.0")] +[assembly: AssemblyFileVersion("2.4.2.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 1bd8b666a..d7765ade8 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -652,6 +652,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Ver 2.4.3-dev(2019/xx/xx) + /// ///==== Ver 2.4.2(2019/10/23) /// * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 /// * FIX: エラー発生時にステータスバーの縦幅が2行分に広がり戻らなくなる場合がある不具合を修正 @@ -665,8 +667,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { ///==== Ver 2.4.0(2019/09/24) /// * NEW: Twemoji 12.0.0 に対応しました /// - Unicode 12.0 で追加された絵文字が表示されるようになります - /// * CHG: DMの送信が完了したらDirectタブに送信したDMを即座に反映する - /// * [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * CHG: DMの送信 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index f7c83dd8e..1f43987fb 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Ver 2.4.3-dev(2019/xx/xx) + ==== Ver 2.4.2(2019/10/23) * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 * FIX: エラー発生時にステータスバーの縦幅が2行分に広がり戻らなくなる場合がある不具合を修正 diff --git a/appveyor.yml b/appveyor.yml index dd249e01b..3ce1e32a3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.4.1.{build} +version: 2.4.2.{build} os: Visual Studio 2019 From 06b3944b574fdd23a04d956f3fff1700bd586844 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 13 Nov 2019 23:01:42 +0900 Subject: [PATCH 017/402] =?UTF-8?q?RelatedPostsTabModel=E3=81=AE=E8=AA=AD?= =?UTF-8?q?=E3=81=BF=E8=BE=BC=E3=81=BF=E4=B8=AD=E3=81=AB=E3=82=BF=E3=83=96?= =?UTF-8?q?=E3=82=92=E9=96=89=E3=81=98=E3=82=8B=E3=81=A8KeyNotFoundExcepti?= =?UTF-8?q?on=E3=81=8C=E7=99=BA=E7=94=9F=E3=81=99=E3=82=8B=E4=B8=8D?= =?UTF-8?q?=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TweenMain.OpenRelatedTab 内の2回目の TabCollection.IndexOf でエラーになる --- OpenTween.Tests/ExtensionsTest.cs | 26 ++++++ OpenTween.Tests/Models/TabCollectionTest.cs | 87 +++++++++++++++++++++ OpenTween/Extensions.cs | 21 +++++ OpenTween/Models/TabCollection.cs | 12 ++- OpenTween/Resources/ChangeLog.txt | 1 + 5 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 OpenTween.Tests/Models/TabCollectionTest.cs diff --git a/OpenTween.Tests/ExtensionsTest.cs b/OpenTween.Tests/ExtensionsTest.cs index 7ee7cc092..f117b73b5 100644 --- a/OpenTween.Tests/ExtensionsTest.cs +++ b/OpenTween.Tests/ExtensionsTest.cs @@ -59,6 +59,32 @@ public void Contains_InvariantCultureTest() Assert.True(CultureInfo.InvariantCulture.Contains(CultureInfo.InvariantCulture)); } + [Theory] + [InlineData("aaa", new string[0], -1)] + [InlineData("aaa", new[] { "aaa" }, 0)] + [InlineData("bbb", new[] { "aaa" }, -1)] + [InlineData("bbb", new[] { "aaa", "bbb" }, 1)] + public void FindIndex_Test(string item, string[] array, int expected) + { + // このテストでは items が List または T[] のインスタンスと認識されないようにする + var items = new LinkedList(array).AsEnumerable(); + Assert.Equal(expected, items.FindIndex(x => x == item)); + } + + [Fact] + public void FindIndex_ListTest() + { + var items = new List { "aaa", "bbb" }.AsEnumerable(); + Assert.Equal(1, items.FindIndex(x => x == "bbb")); + } + + [Fact] + public void FindIndex_ArrayTest() + { + var items = new[] { "aaa", "bbb" }.AsEnumerable(); + Assert.Equal(1, items.FindIndex(x => x == "bbb")); + } + [Theory] [InlineData("abc", new int[] { 'a', 'b', 'c' })] [InlineData("🍣", new int[] { 0x1f363 })] // サロゲートペア diff --git a/OpenTween.Tests/Models/TabCollectionTest.cs b/OpenTween.Tests/Models/TabCollectionTest.cs new file mode 100644 index 000000000..40d9491a2 --- /dev/null +++ b/OpenTween.Tests/Models/TabCollectionTest.cs @@ -0,0 +1,87 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2019 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween.Models +{ + public class TabCollectionTest + { + [Fact] + public void Getter_Test() + { + var tabs = new TabCollection(); + var tab = new PublicSearchTabModel("hoge"); + tabs.Add(tab); + + Assert.Equal(tab, tabs["hoge"]); + } + + [Fact] + public void IndexOf_TabName_Test() + { + var tabs = new TabCollection(); + var tab1 = new PublicSearchTabModel("aaaaa"); + var tab2 = new PublicSearchTabModel("bbbbb"); + + tabs.Add(tab1); + tabs.Add(tab2); + + Assert.Equal(1, tabs.IndexOf("bbbbb")); + } + + [Fact] + public void IndexOf_TabName_NotExistsTest() + { + var tabs = new TabCollection(); + + Assert.Equal(-1, tabs.IndexOf("hoge")); + } + + [Fact] + public void TryGetValue_TabName_Test() + { + var tabs = new TabCollection(); + var tab1 = new PublicSearchTabModel("aaaaa"); + var tab2 = new PublicSearchTabModel("bbbbb"); + + tabs.Add(tab1); + tabs.Add(tab2); + + Assert.True(tabs.TryGetValue("bbbbb", out var actualTab)); + Assert.Equal(tab2, actualTab); + } + + [Fact] + public void TryGetValue_TabName_NotExistsTest() + { + var tabs = new TabCollection(); + + Assert.False(tabs.TryGetValue("hoge", out var actualTab)); + Assert.Null(actualTab); + } + } +} diff --git a/OpenTween/Extensions.cs b/OpenTween/Extensions.cs index a31adbbe6..069a9e399 100644 --- a/OpenTween/Extensions.cs +++ b/OpenTween/Extensions.cs @@ -70,6 +70,27 @@ public static bool Contains(this CultureInfo @this, CultureInfo that) return false; } + public static int FindIndex(this IEnumerable enumerable, Predicate finder) + { + if (enumerable is List list) + return list.FindIndex(finder); + + if (enumerable is T[] array) + return Array.FindIndex(array, finder); + + var index = 0; + + foreach (var item in enumerable) + { + if (finder(item)) + return index; + + index++; + } + + return -1; + } + public static IEnumerable<(T Value, int Index)> WithIndex(this IEnumerable enumerable) { var i = 0; diff --git a/OpenTween/Models/TabCollection.cs b/OpenTween/Models/TabCollection.cs index 45922f8a6..086ead0a6 100644 --- a/OpenTween/Models/TabCollection.cs +++ b/OpenTween/Models/TabCollection.cs @@ -23,16 +23,24 @@ using System.Collections.ObjectModel; using System.Diagnostics.CodeAnalysis; +using System.Linq; namespace OpenTween.Models { public class TabCollection : KeyedCollection, IReadOnlyTabCollection { public int IndexOf(string tabName) - => this.IndexOf(this[tabName]); + => this.Items.FindIndex(x => x.TabName == tabName); public bool TryGetValue(string tabName, [NotNullWhen(true)] out TabModel? tab) - => this.Dictionary.TryGetValue(tabName, out tab); + { + if (this.Dictionary is { } dict) + return dict.TryGetValue(tabName, out tab); + + tab = this.Items.FirstOrDefault(x => x.TabName == tabName); + + return tab != null; + } protected override string GetKeyForItem(TabModel tab) => tab.TabName; diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 1f43987fb..c49069c30 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Ver 2.4.3-dev(2019/xx/xx) + * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 ==== Ver 2.4.2(2019/10/23) * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 From ab5da426b685b5d525279c27d5bd4e78921c80e8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 1 Dec 2019 00:13:32 +0900 Subject: [PATCH 018/402] =?UTF-8?q?RefreshTasktrayIcon=E3=81=A7=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=81=8C=E7=99=BA=E7=94=9F=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=81=A8workerSemaphore=E3=81=8C=E9=96=8B=E6=94=BE=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=AA=E3=81=84=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit タスクトレイアイコンがbusy表示のままになる原因とも言えそうなものの、 RefreshTasktrayIconでエラーが発生する問題が発見されたわけではないので依然として謎なまま --- OpenTween/Tween.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 7756c6de6..8536445ec 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2323,10 +2323,10 @@ private Task RefreshTabAsync(TabModel tab) private async Task RefreshTabAsync(TabModel tab, bool backward) { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { + this.RefreshTasktrayIcon(); await Task.Run(() => tab.RefreshAsync(this.tw, backward, this._initial, this.workerProgress)); this.RefreshTimeline(); } @@ -2356,12 +2356,12 @@ private async Task RefreshTabAsync(TabModel tab, bool backward) private async Task FavAddAsync(long statusId, TabModel tab) { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { var progress = new Progress(x => this.StatusLabel.Text = x); + this.RefreshTasktrayIcon(); await this.FavAddAsyncInternal(progress, this.workerCts.Token, statusId, tab); } catch (WebApiException ex) @@ -2476,12 +2476,12 @@ await this.twitterApi.FavoritesCreate(post.RetweetedId ?? post.StatusId) private async Task FavRemoveAsync(IReadOnlyList statusIds, TabModel tab) { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { var progress = new Progress(x => this.StatusLabel.Text = x); + this.RefreshTasktrayIcon(); await this.FavRemoveAsyncInternal(progress, this.workerCts.Token, statusIds, tab); } catch (WebApiException ex) @@ -2591,12 +2591,12 @@ await this.twitterApi.FavoritesDestroy(post.RetweetedId ?? post.StatusId) private async Task PostMessageAsync(PostStatusParams postParams, IMediaUploadService? uploadService, IMediaItem[]? uploadItems) { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { var progress = new Progress(x => this.StatusLabel.Text = x); + this.RefreshTasktrayIcon(); await this.PostMessageAsyncInternal(progress, this.workerCts.Token, postParams, uploadService, uploadItems); } catch (WebApiException ex) @@ -2738,12 +2738,12 @@ await Task.Run(async () => private async Task RetweetAsync(IReadOnlyList statusIds) { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { var progress = new Progress(x => this.StatusLabel.Text = x); + this.RefreshTasktrayIcon(); await this.RetweetAsyncInternal(progress, this.workerCts.Token, statusIds); } catch (WebApiException ex) @@ -2818,10 +2818,10 @@ await Task.Run(async () => private async Task RefreshFollowerIdsAsync() { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { + this.RefreshTasktrayIcon(); this.StatusLabel.Text = Properties.Resources.UpdateFollowersMenuItem1_ClickText1; await this.tw.RefreshFollowerIds(); @@ -2845,10 +2845,10 @@ private async Task RefreshFollowerIdsAsync() private async Task RefreshNoRetweetIdsAsync() { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { + this.RefreshTasktrayIcon(); await this.tw.RefreshNoRetweetIds(); this.StatusLabel.Text = "NoRetweetIds refreshed"; @@ -2866,10 +2866,10 @@ private async Task RefreshNoRetweetIdsAsync() private async Task RefreshBlockIdsAsync() { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { + this.RefreshTasktrayIcon(); this.StatusLabel.Text = Properties.Resources.UpdateBlockUserText1; await this.tw.RefreshBlockIds(); @@ -2889,10 +2889,10 @@ private async Task RefreshBlockIdsAsync() private async Task RefreshTwitterConfigurationAsync() { await this.workerSemaphore.WaitAsync(); - this.RefreshTasktrayIcon(); try { + this.RefreshTasktrayIcon(); await this.tw.RefreshConfiguration(); if (this.tw.Configuration.PhotoSizeLimit != 0) From 7f0bea3a3a6140583016fbd04f9eca41be1a9ba8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 1 Dec 2019 00:17:36 +0900 Subject: [PATCH 019/402] =?UTF-8?q?TimelineScheduler.Update*=20=E3=81=AEde?= =?UTF-8?q?legate=E3=82=92=20Task.Run=20=E3=81=AE=E5=86=85=E5=81=B4?= =?UTF-8?q?=E3=81=A7=E5=AE=9F=E8=A1=8C=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit delegate 内で例外が発生した場合に RunUpdateTasks の途中で中断されてしまうのを防ぐため --- OpenTween/TimelineScheduler.cs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/OpenTween/TimelineScheduler.cs b/OpenTween/TimelineScheduler.cs index 2006800ef..07648d814 100644 --- a/OpenTween/TimelineScheduler.cs +++ b/OpenTween/TimelineScheduler.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -239,61 +240,59 @@ private async Task TimerCallback_AfterSystemResume() private async Task RunUpdateTasks(UpdateTask tasks, DateTimeUtc now) { - var updateTasks = new List(capacity: 7); - - // LastUpdate* を次の時刻に更新してから Update* を実行すること - // (LastUpdate* が更新されずに Update* が例外を投げると無限ループに陥る) + var updateTasks = new List>(capacity: 7); if ((tasks & UpdateTask.Home) == UpdateTask.Home) { this.LastUpdateHome = now; if (this.UpdateHome != null) - updateTasks.Add(this.UpdateHome()); + updateTasks.Add(this.UpdateHome); } if ((tasks & UpdateTask.Mention) == UpdateTask.Mention) { this.LastUpdateMention = now; if (this.UpdateMention != null) - updateTasks.Add(this.UpdateMention()); + updateTasks.Add(this.UpdateMention); } if ((tasks & UpdateTask.Dm) == UpdateTask.Dm) { this.LastUpdateDm = now; if (this.UpdateDm != null) - updateTasks.Add(this.UpdateDm()); + updateTasks.Add(this.UpdateDm); } if ((tasks & UpdateTask.PublicSearch) == UpdateTask.PublicSearch) { this.LastUpdatePublicSearch = now; if (this.UpdatePublicSearch != null) - updateTasks.Add(this.UpdatePublicSearch()); + updateTasks.Add(this.UpdatePublicSearch); } if ((tasks & UpdateTask.User) == UpdateTask.User) { this.LastUpdateUser = now; if (this.UpdateUser != null) - updateTasks.Add(this.UpdateUser()); + updateTasks.Add(this.UpdateUser); } if ((tasks & UpdateTask.List) == UpdateTask.List) { this.LastUpdateList = now; if (this.UpdateList != null) - updateTasks.Add(this.UpdateList()); + updateTasks.Add(this.UpdateList); } if ((tasks & UpdateTask.Config) == UpdateTask.Config) { this.LastUpdateConfig = now; if (this.UpdateConfig != null) - updateTasks.Add(this.UpdateConfig()); + updateTasks.Add(this.UpdateConfig); } - await Task.WhenAll(updateTasks).ConfigureAwait(false); + await Task.WhenAll(updateTasks.Select(x => Task.Run(x))) + .ConfigureAwait(false); } private TimeSpan NextTimerDelay() From 8e8788eaca06c691d5ac6ba550d03042f8f229e0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 6 Dec 2019 00:47:40 +0900 Subject: [PATCH 020/402] =?UTF-8?q?=E6=93=8D=E4=BD=9C=E3=83=A1=E3=83=8B?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E3=81=AE=E3=80=8C=E3=82=BF=E3=83=96=E6=8C=AF?= =?UTF-8?q?=E3=82=8A=E5=88=86=E3=81=91=E3=83=AB=E3=83=BC=E3=83=AB=E4=BD=9C?= =?UTF-8?q?=E6=88=90=E3=80=8D=E3=81=8B=E3=82=89=E6=96=B0=E8=A6=8F=E3=82=BF?= =?UTF-8?q?=E3=83=96=E3=82=92=E4=BD=9C=E6=88=90=E3=81=99=E3=82=8B=E3=81=A8?= =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=8C=E7=99=BA=E7=94=9F=E3=81=99?= =?UTF-8?q?=E3=82=8B=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FilterDialogのタブ一覧はコンストラクタ内で生成しているため、 タブ選択画面(新規タブ作成の操作も行える)の後にFilterDialogインスタンスを生成するように順序を変更した https://osdn.net/projects/opentween/ticket/39821 --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 17 +++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index c49069c30..cc7af89a1 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Ver 2.4.3-dev(2019/xx/xx) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 + * FIX: 操作メニューの「タブ振り分けルール作成」から新規タブを作成するとエラーが発生する不具合を修正 ==== Ver 2.4.2(2019/10/23) * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 8536445ec..60092d523 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -7959,16 +7959,16 @@ private async void AddTabMenuItem_Click(object sender, EventArgs e) private void TabMenuItem_Click(object sender, EventArgs e) { - using (var fltDialog = new FilterDialog()) + // 選択発言を元にフィルタ追加 + foreach (var post in this.CurrentTab.SelectedPosts) { - fltDialog.Owner = this; + // タブ選択(or追加) + if (!SelectTab(out var tab)) + return; - //選択発言を元にフィルタ追加 - foreach (var post in this.CurrentTab.SelectedPosts) + using (var fltDialog = new FilterDialog()) { - //タブ選択(or追加) - if (!SelectTab(out var tab)) return; - + fltDialog.Owner = this; fltDialog.SetCurrent(tab.TabName); if (post.RetweetedBy == null) @@ -7980,8 +7980,9 @@ private void TabMenuItem_Click(object sender, EventArgs e) fltDialog.AddNewFilter(post.RetweetedBy, post.TextFromApi); } fltDialog.ShowDialog(this); - this.TopMost = SettingManager.Common.AlwaysTop; } + + this.TopMost = SettingManager.Common.AlwaysTop; } this.ApplyPostFilters(); From d18867aca3ffc0b3dd569d42d910f3e7f040be4f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 6 Dec 2019 02:23:12 +0900 Subject: [PATCH 021/402] =?UTF-8?q?OpenTween=20v2.4.3=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 9 ++++----- OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index ee4a10aee..b3acfc75f 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.4.2.1")] +[assembly: AssemblyFileVersion("2.4.3.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index d7765ade8..b95472b99 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -652,7 +652,9 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Ver 2.4.3-dev(2019/xx/xx) + ///==== Ver 2.4.3(2019/12/06) + /// * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 + /// * FIX: 操作メニューの「タブ振り分けルール作成」から新規タブを作成するとエラーが発生する不具合を修正 /// ///==== Ver 2.4.2(2019/10/23) /// * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 @@ -664,10 +666,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 /// * FIX: 更新間隔を0秒に設定した場合に自動更新が停止されない不具合を修正 (thx @kamemory!) /// - ///==== Ver 2.4.0(2019/09/24) - /// * NEW: Twemoji 12.0.0 に対応しました - /// - Unicode 12.0 で追加された絵文字が表示されるようになります - /// * CHG: DMの送信 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + ///==== Ver 2.4.0(201 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index cc7af89a1..d522ab8fd 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Ver 2.4.3-dev(2019/xx/xx) +==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 * FIX: 操作メニューの「タブ振り分けルール作成」から新規タブを作成するとエラーが発生する不具合を修正 From e0710bf67907047f2be3ba5c202ab30091529331 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 6 Dec 2019 02:25:35 +0900 Subject: [PATCH 022/402] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.4.4-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 6 +++--- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index b3acfc75f..8d5a49c66 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -33,7 +33,7 @@ // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.4.3.0")] +[assembly: AssemblyFileVersion("2.4.3.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index b95472b99..4d26930f7 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -652,6 +652,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Ver 2.4.4-dev(2019/xx/xx) + /// ///==== Ver 2.4.3(2019/12/06) /// * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 /// * FIX: 操作メニューの「タブ振り分けルール作成」から新規タブを作成するとエラーが発生する不具合を修正 @@ -664,9 +666,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { ///==== Ver 2.4.1(2019/09/25) /// * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) /// * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 - /// * FIX: 更新間隔を0秒に設定した場合に自動更新が停止されない不具合を修正 (thx @kamemory!) - /// - ///==== Ver 2.4.0(201 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: 更新間隔を0秒に設定した場合に自動更新が停止されない不具合を修正 (thx [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index d522ab8fd..a8e1e4c4d 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Ver 2.4.4-dev(2019/xx/xx) + ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 * FIX: 操作メニューの「タブ振り分けルール作成」から新規タブを作成するとエラーが発生する不具合を修正 diff --git a/appveyor.yml b/appveyor.yml index 3ce1e32a3..a7278701f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.4.2.{build} +version: 2.4.3.{build} os: Visual Studio 2019 From 89a2019bd7ef08770232c3e77727b10fd8dc5832 Mon Sep 17 00:00:00 2001 From: naminodarie Date: Thu, 2 Jan 2020 02:13:54 +0900 Subject: [PATCH 023/402] =?UTF-8?q?=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC?= =?UTF-8?q?=E6=83=85=E5=A0=B1=E3=81=A7=E5=A4=A7=E6=96=87=E5=AD=97=E3=82=A2?= =?UTF-8?q?=E3=83=AB=E3=83=95=E3=82=A1=E3=83=99=E3=83=83=E3=83=88=E3=81=8C?= =?UTF-8?q?=E3=83=8F=E3=83=83=E3=82=B7=E3=83=A5=E3=82=BF=E3=82=B0=E3=81=A8?= =?UTF-8?q?=E3=81=97=E3=81=A6=E8=AA=8D=E8=AD=98=E3=81=95=E3=82=8C=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=AA=E3=81=8B=E3=81=A3=E3=81=9F=E3=81=AE=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Twitter.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index b9aa67a11..52127465c 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -76,9 +76,9 @@ public class Twitter : IDisposable private const string NON_LATIN_HASHTAG_CHARS = @"\u0400-\u04ff\u0500-\u0527\u1100-\u11ff\u3130-\u3185\uA960-\uA97F\uAC00-\uD7AF\uD7B0-\uD7FF"; private const string CJ_HASHTAG_CHARACTERS = @"\u30A1-\u30FA\u30FC\u3005\uFF66-\uFF9F\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\u3041-\u309A\u3400-\u4DBF\p{IsCJKUnifiedIdeographs}"; private const string HASHTAG_BOUNDARY = @"^|$|\s|「|」|。|\.|!"; - private const string HASHTAG_ALPHA = "[a-z_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; - private const string HASHTAG_ALPHANUMERIC = "[a-z0-9_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; - private const string HASHTAG_TERMINATOR = "[^a-z0-9_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; + private const string HASHTAG_ALPHA = "[A-Za-z_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; + private const string HASHTAG_ALPHANUMERIC = "[A-Za-z0-9_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; + private const string HASHTAG_TERMINATOR = "[^A-Za-z0-9_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; public const string HASHTAG = "(" + HASHTAG_BOUNDARY + ")(#|#)(" + HASHTAG_ALPHANUMERIC + "*" + HASHTAG_ALPHA + HASHTAG_ALPHANUMERIC + "*)(?=" + HASHTAG_TERMINATOR + "|" + HASHTAG_BOUNDARY + ")"; //URL正規表現 private const string url_valid_preceding_chars = @"(?:[^A-Za-z0-9@@$##\ufffe\ufeff\uffff\u202a-\u202e]|^)"; From 5bd22d86e4d082ddf81130c0d05fd249b9d5007b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 19 Jan 2020 08:11:54 +0900 Subject: [PATCH 024/402] =?UTF-8?q?pbs.twimg.com=20=E3=81=AE=E7=94=BB?= =?UTF-8?q?=E5=83=8FURL=E3=81=AE=E3=83=95=E3=82=A9=E3=83=BC=E3=83=9E?= =?UTF-8?q?=E3=83=83=E3=83=88=E5=A4=89=E6=9B=B4=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/entities-object#photo_format --- .../Thumbnail/Services/PbsTwimgComTest.cs | 126 ++++++++++++++++++ OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Thumbnail/Services/PbsTwimgCom.cs | 50 +++++-- 3 files changed, 164 insertions(+), 13 deletions(-) create mode 100644 OpenTween.Tests/Thumbnail/Services/PbsTwimgComTest.cs diff --git a/OpenTween.Tests/Thumbnail/Services/PbsTwimgComTest.cs b/OpenTween.Tests/Thumbnail/Services/PbsTwimgComTest.cs new file mode 100644 index 000000000..2c70e8e5e --- /dev/null +++ b/OpenTween.Tests/Thumbnail/Services/PbsTwimgComTest.cs @@ -0,0 +1,126 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2020 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; +using OpenTween.Models; +using Xunit; + +namespace OpenTween.Thumbnail.Services +{ + public class PbsTwimgComTest + { + [Fact] + public void ModernUrlPattern_Test() + { + var mediaUrl = "https://pbs.twimg.com/media/DYlFv51VwAUdqWr?format=jpg&name=large"; + var matches = PbsTwimgCom.ModernUrlPattern.Match(mediaUrl); + + Assert.True(matches.Success); + Assert.Equal("https://pbs.twimg.com/media/DYlFv51VwAUdqWr", matches.Groups["base_url"].Value); + Assert.Equal("jpg", matches.Groups["format"].Value); + } + + [Fact] + public void ModernUrlPattern_UnorderedTest() + { + var mediaUrl = "https://pbs.twimg.com/media/DYlFv51VwAUdqWr?name=large&format=jpg"; + var matches = PbsTwimgCom.ModernUrlPattern.Match(mediaUrl); + + Assert.True(matches.Success); + Assert.Equal("https://pbs.twimg.com/media/DYlFv51VwAUdqWr", matches.Groups["base_url"].Value); + Assert.Equal("jpg", matches.Groups["format"].Value); + } + + [Fact] + public void ModernUrlPattern_LegacyUrlTest() + { + var mediaUrl = "https://pbs.twimg.com/media/DYlFv51VwAUdqWr.jpg:large"; + var matches = PbsTwimgCom.ModernUrlPattern.Match(mediaUrl); + + Assert.False(matches.Success); + } + + [Fact] + public void LegacyUrlPattern_Test() + { + var mediaUrl = "https://pbs.twimg.com/media/DYlFv51VwAUdqWr.jpg"; + var matches = PbsTwimgCom.LegacyUrlPattern.Match(mediaUrl); + + Assert.True(matches.Success); + Assert.Equal("https://pbs.twimg.com/media/DYlFv51VwAUdqWr", matches.Groups["base_url"].Value); + Assert.Equal("jpg", matches.Groups["format"].Value); + } + + [Fact] + public void LegacyUrlPattern_SizeNameTest() + { + var mediaUrl = "https://pbs.twimg.com/media/DYlFv51VwAUdqWr.jpg:large"; + var matches = PbsTwimgCom.LegacyUrlPattern.Match(mediaUrl); + + Assert.True(matches.Success); + Assert.Equal("https://pbs.twimg.com/media/DYlFv51VwAUdqWr", matches.Groups["base_url"].Value); + Assert.Equal("jpg", matches.Groups["format"].Value); + } + + [Fact] + public void LegacyUrlPattern_ModernUrlTest() + { + var mediaUrl = "https://pbs.twimg.com/media/DYlFv51VwAUdqWr?format=jpg&name=large"; + var matches = PbsTwimgCom.LegacyUrlPattern.Match(mediaUrl); + + Assert.False(matches.Success); + } + + [Fact] + public async Task GetThumbnailInfoAsync_ModernUrlTest() + { + var mediaUrl = "https://pbs.twimg.com/media/DYlFv51VwAUdqWr?format=jpg&name=large"; + + var service = new PbsTwimgCom(); + var thumb = await service.GetThumbnailInfoAsync(mediaUrl, new PostClass(), CancellationToken.None) + .ConfigureAwait(false); + + Assert.NotNull(thumb); + Assert.Equal("https://pbs.twimg.com/media/DYlFv51VwAUdqWr?format=jpg&name=large", thumb!.ThumbnailImageUrl); + Assert.Equal("https://pbs.twimg.com/media/DYlFv51VwAUdqWr?format=jpg&name=orig", thumb!.FullSizeImageUrl); + } + + [Fact] + public async Task GetThumbnailInfoAsync_LegacyUrlTest() + { + var mediaUrl = "https://pbs.twimg.com/media/DYlFv51VwAUdqWr.jpg"; + + var service = new PbsTwimgCom(); + var thumb = await service.GetThumbnailInfoAsync(mediaUrl, new PostClass(), CancellationToken.None) + .ConfigureAwait(false); + + Assert.NotNull(thumb); + Assert.Equal("https://pbs.twimg.com/media/DYlFv51VwAUdqWr?format=jpg&name=large", thumb!.ThumbnailImageUrl); + Assert.Equal("https://pbs.twimg.com/media/DYlFv51VwAUdqWr?format=jpg&name=orig", thumb!.FullSizeImageUrl); + } + } +} diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index a8e1e4c4d..0865de170 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Ver 2.4.4-dev(2019/xx/xx) + * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 diff --git a/OpenTween/Thumbnail/Services/PbsTwimgCom.cs b/OpenTween/Thumbnail/Services/PbsTwimgCom.cs index 8e65b07c4..b05440e0f 100644 --- a/OpenTween/Thumbnail/Services/PbsTwimgCom.cs +++ b/OpenTween/Thumbnail/Services/PbsTwimgCom.cs @@ -32,28 +32,52 @@ namespace OpenTween.Thumbnail.Services { - class PbsTwimgCom : SimpleThumbnailService + class PbsTwimgCom : IThumbnailService { - public static readonly string UrlPattern = @"^(https?://pbs\.twimg\.com/[^:]+)(?:\:.+)?$"; + public static readonly Regex ModernUrlPattern = + new Regex(@"^(?https?://pbs\.twimg\.com/[^:.]+)\?([^&]+?&)?format=(?[A-Za-z]+)"); - public PbsTwimgCom() - : base(UrlPattern, "${1}", "${1}:orig") - { - } + public static readonly Regex LegacyUrlPattern = + new Regex(@"^(?https?://pbs\.twimg\.com/[^.]+)\.(?[A-Za-z]+)(?:\:.+)?$"); + + public override Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) + => Task.FromResult(this.GetThumbnailInfo(url, post, token)); - public override async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) + private ThumbnailInfo? GetThumbnailInfo(string url, PostClass post, CancellationToken token) { - var thumb = await base.GetThumbnailInfoAsync(url, post, token) - .ConfigureAwait(false); + string baseUrl; + string format; - if (thumb == null) + // 現状の Twitter API から返る media_url_https は LegacyUrlPettern の形式になっているが、 + // どちらの形式でも動くようにする + if (ModernUrlPattern.Match(url) is { Success: true } matchesModern) + { + baseUrl = matchesModern.Groups["base_url"].Value; + format = matchesModern.Groups["format"].Value; + } + else if (LegacyUrlPattern.Match(url) is { Success: true } matchesLegacy) + { + baseUrl = matchesLegacy.Groups["base_url"].Value; + format = matchesLegacy.Groups["format"].Value; + } + else + { return null; + } + + var mediaOrig = $"{baseUrl}?format={format}&name=orig"; + var mediaLarge = $"{baseUrl}?format={format}&name=large"; var media = post.Media.FirstOrDefault(x => x.Url == url); - if (media != null) + var altText = media?.AltText; + + var thumb = new ThumbnailInfo { - thumb.TooltipText = media.AltText; - } + MediaPageUrl = mediaOrig, + ThumbnailImageUrl = mediaLarge, + TooltipText = altText, + FullSizeImageUrl = mediaOrig, + }; return thumb; } From 7e58b75f1c48dcc5bf64083b3bdab5b3c27161c1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 19 Jan 2020 08:17:07 +0900 Subject: [PATCH 025/402] =?UTF-8?q?ton.twitter.com=20=E3=81=AE=E7=94=BB?= =?UTF-8?q?=E5=83=8F=E3=82=92=E3=83=96=E3=83=A9=E3=82=A6=E3=82=B6=E3=81=A7?= =?UTF-8?q?=E9=96=8B=E3=81=8F=E9=9A=9B=E3=81=AB=20:large=20=E3=82=92?= =?UTF-8?q?=E4=BB=98=E3=81=91=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit この形式のURLであれば、Twitterにログインしている状態のセッションCookieがあれば画像を閲覧できる --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Thumbnail/Services/TonTwitterCom.cs | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 0865de170..44fbc7db1 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Ver 2.4.4-dev(2019/xx/xx) * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 + * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 diff --git a/OpenTween/Thumbnail/Services/TonTwitterCom.cs b/OpenTween/Thumbnail/Services/TonTwitterCom.cs index 5c45da457..72b774b51 100644 --- a/OpenTween/Thumbnail/Services/TonTwitterCom.cs +++ b/OpenTween/Thumbnail/Services/TonTwitterCom.cs @@ -52,12 +52,14 @@ class TonTwitterCom : IThumbnailService if (!url.StartsWith(@"https://ton.twitter.com/1.1/ton/data/", StringComparison.Ordinal)) return null; + var largeUrl = url + ":large"; + return new TonTwitterCom.Thumbnail { - MediaPageUrl = url, + MediaPageUrl = largeUrl, ThumbnailImageUrl = url, TooltipText = null, - FullSizeImageUrl = url, + FullSizeImageUrl = largeUrl, }; }, token); } From b2ddee6dc477500dcd75a85eca04992e9017ba77 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 19 Jan 2020 08:54:18 +0900 Subject: [PATCH 026/402] =?UTF-8?q?ChangeLog=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 89a2019bd7ef08770232c3e77727b10fd8dc5832 の変更を反映 --- OpenTween/Resources/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 44fbc7db1..75b85ffef 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -3,6 +3,7 @@ ==== Ver 2.4.4-dev(2019/xx/xx) * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 + * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 From 39a3c86501fcc5a2e2585d727159dde5fd9c68af Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 7 Mar 2020 23:53:21 +0900 Subject: [PATCH 027/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E9=81=B8=E6=8A=9E=E7=8A=B6=E6=85=8B=E3=82=92=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E3=81=99=E3=82=8B=E9=9A=9B=E3=81=AB=E9=81=B8=E6=8A=9E?= =?UTF-8?q?=E7=AF=84=E5=9B=B2=E3=81=AE=E5=B7=AE=E5=88=86=E3=81=AE=E3=81=BF?= =?UTF-8?q?=E5=8F=8D=E6=98=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/DetailsListView.cs | 36 ++++++++++++++++++++++++++++++------ OpenTween/NativeMethods.cs | 5 +++-- OpenTween/Tween.cs | 5 ----- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index cf6f1ab55..23ad4cb99 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -70,15 +70,39 @@ public int SelectionMark public void SelectItems(int[] indices) { - foreach (var index in indices) - { - if (index < 0 || index >= this.VirtualListSize) - throw new ArgumentOutOfRangeException(nameof(indices)); + var listSize = this.VirtualListSize; + if (indices.Any(x => x < 0 || x >= listSize)) + throw new ArgumentOutOfRangeException(nameof(indices)); - NativeMethods.SelectItem(this, index); + if (indices.Length == 0) + { + this.SelectedIndices.Clear(); } + else if (indices.Length == 1) + { + this.SelectedIndices.Clear(); + this.SelectedIndices.Add(indices[0]); + } + else + { + var currentSelectedIndices = this.SelectedIndices.Cast().ToArray(); + var selectIndices = indices.Except(currentSelectedIndices).ToArray(); + var deselectIndices = currentSelectedIndices.Except(indices).ToArray(); - this.OnSelectedIndexChanged(EventArgs.Empty); + if (selectIndices.Length + deselectIndices.Length > currentSelectedIndices.Length) + { + // Clearして選択し直した方が早い場合 + this.SelectedIndices.Clear(); + selectIndices = indices; + deselectIndices = Array.Empty(); + } + + foreach (var index in selectIndices) + NativeMethods.SelectItem(this, index, selected: true); + + foreach (var index in deselectIndices) + NativeMethods.SelectItem(this, index, selected: false); + } } public void SelectAllItems() diff --git a/OpenTween/NativeMethods.cs b/OpenTween/NativeMethods.cs index 209824ff6..6d972c62c 100644 --- a/OpenTween/NativeMethods.cs +++ b/OpenTween/NativeMethods.cs @@ -121,6 +121,7 @@ private struct LVITEM [Flags] private enum LVIS : uint { + None = 0, SELECTED = 0x02, } @@ -130,13 +131,13 @@ private enum LVIS : uint /// 対象となる ListView /// 選択するアイテムのインデックス /// 成功した場合は true、それ以外の場合は false - public static bool SelectItem(ListView listView, int index) + public static bool SelectItem(ListView listView, int index, bool selected = true) { // LVM_SETITEMSTATE では stateMask, state 以外のメンバーは無視される var lvitem = new LVITEM { stateMask = LVIS.SELECTED, - state = LVIS.SELECTED, + state = selected ? LVIS.SELECTED : LVIS.None, }; var ret = (int)SendMessage(listView.Handle, SendMessageType.LVM_SETITEMSTATE, (IntPtr)index, ref lvitem); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 60092d523..8326f99bc 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -9552,11 +9552,6 @@ private void SelectListItem(DetailsListView LView , int[]? Index, int focusedInd if (Index != null) { - do - { - LView.SelectedIndices.Clear(); - } - while (LView.SelectedIndices.Count > 0); LView.SelectItems(Index); } if (selectionMarkIndex > -1 && LView.VirtualListSize > selectionMarkIndex) From b9a985275331d64bc9b742a88a94c99fe8a12d38 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 8 Mar 2020 00:44:23 +0900 Subject: [PATCH 028/402] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AA=20ListView.?= =?UTF-8?q?SelectedIndices=20=E3=81=B8=E3=81=AE=E5=8F=82=E7=85=A7=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Tween.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 8326f99bc..6171cc850 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1942,10 +1942,10 @@ private void MyList_SelectedIndexChanged(object sender, EventArgs e) var indices = listView.SelectedIndices.Cast().ToArray(); this.CurrentTab.SelectPosts(indices); - if (listView.SelectedIndices.Count != 1) + if (indices.Length != 1) return; - var index = listView.SelectedIndices[0]; + var index = indices[0]; if (index > listView.VirtualListSize - 1) return; this.PushSelectPostChain(); From bfa3997baa0ea9b57e5beb4607ebe0a8fd2fb174 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 13 Mar 2020 05:31:05 +0900 Subject: [PATCH 029/402] =?UTF-8?q?ToolStripAPIGauge=E3=81=A7=E3=83=AC?= =?UTF-8?q?=E3=83=BC=E3=83=88=E3=83=AA=E3=83=9F=E3=83=83=E3=83=88=E3=81=8C?= =?UTF-8?q?10=E5=84=84=E5=9B=9E/15=E5=88=86=E3=81=AE=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AE=E3=83=86=E3=82=B9=E3=83=88=E3=82=B3=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/ToolStripAPIGaugeTest.cs | 27 ++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/OpenTween.Tests/ToolStripAPIGaugeTest.cs b/OpenTween.Tests/ToolStripAPIGaugeTest.cs index 90aa99bcf..983967a65 100644 --- a/OpenTween.Tests/ToolStripAPIGaugeTest.cs +++ b/OpenTween.Tests/ToolStripAPIGaugeTest.cs @@ -203,5 +203,32 @@ public void GaugeBoundsTest() MyCommon.TwitterApiInfo.AccessLimit.Clear(); } } + + [Fact] + public void OneBillionTest() + { + using var toolStrip = new TestToolStripAPIGauge(); + + var now = new DateTimeUtc(2020, 2, 25, 19, 0, 0); + toolStrip.DateTimeNow = now; + + toolStrip.AutoSize = false; + toolStrip.Size = new Size(100, 10); + toolStrip.GaugeHeight = 5; + + MyCommon.TwitterApiInfo.AccessLimit["/statuses/user_timeline"] = new ApiLimit( + limitCount: 1_000_000_000, + limitRemain: 999_999_999, + resetDate: now + TimeSpan.FromMinutes(15) + ); + toolStrip.ApiEndpoint = "/statuses/user_timeline"; + + Assert.Equal(new Rectangle(0, 0, 99, 5), toolStrip.apiGaugeBounds); // 99% (999999999/1000000000) + Assert.Equal(new Rectangle(0, 5, 100, 5), toolStrip.timeGaugeBounds); // 100% (15/15) + Assert.Equal("API 999999999/1000000000", toolStrip.Text); + Assert.Equal("API rest /statuses/user_timeline 999999999/1000000000" + Environment.NewLine + "(reset after 15 minutes)", toolStrip.ToolTipText); + + MyCommon.TwitterApiInfo.AccessLimit.Clear(); + } } } From 5d2d9c2c89ad83e9434f5814ebcdf66af98adab4 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 6 Mar 2021 20:04:54 +0900 Subject: [PATCH 030/402] =?UTF-8?q?OpenTween=E3=81=AE=E3=83=90=E3=83=BC?= =?UTF-8?q?=E3=82=B8=E3=83=A7=E3=83=B3=E6=83=85=E5=A0=B1=E3=82=92AssemblyF?= =?UTF-8?q?ileVersion=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8FAssemblyVersion?= =?UTF-8?q?=E3=81=A8=E3=81=97=E3=81=A6=E8=A8=AD=E5=AE=9A=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 手動でリリース版の ZIP アーカイブを作成した時と AppVeyor でビルドされた 開発版のバイナリで、アセンブリに埋め込まれるバージョン情報に差異があったためこれを統一した --- OpenTween/MyCommon.cs | 5 ++--- OpenTween/Properties/AssemblyInfo.cs | 13 +------------ 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 0094be029..82d8ff41f 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -227,9 +227,8 @@ static MyCommon() var assembly = Assembly.GetExecutingAssembly(); MyCommon.EntryAssembly = assembly; - var fileVersionAttribute = (AssemblyFileVersionAttribute)assembly - .GetCustomAttributes(typeof(AssemblyFileVersionAttribute)).First(); - MyCommon.FileVersion = fileVersionAttribute.Version; + var assemblyVersion = assembly.GetName().Version; + MyCommon.FileVersion = assemblyVersion.ToString(); } public static string GetErrorLogPath() diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 8d5a49c66..3eeb21e18 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,18 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を -// 既定値にすることができます: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.1.0.0")] -[assembly: AssemblyFileVersion("2.4.3.1")] +[assembly: AssemblyVersion("2.4.3.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq From 811f69c8873518e3a5e69645e43fc65f7a0825a8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 6 Mar 2021 20:10:27 +0900 Subject: [PATCH 031/402] =?UTF-8?q?Reproducible=20Build=20=E3=81=AB?= =?UTF-8?q?=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新たに追加された tools/build-zip-archive.ps1 を使用して ZIP アーカイブを作成すると、同一のソースコードからのビルドであれば誰の環境で実行しても常に同一のファイルが生成されるようになる。 これにより、OpenTween のリリース版として公開しているバイナリのチェックサムは、第三者の環境で同じようにビルドしても同一の値になるはずであるため、OSS として公開されているソースコードを改変することなくビルドしていることが容易に検証できるようになる 参考: https://wiki.debian.org/ja/ReproducibleBuilds/About --- OpenTween/OpenTween.csproj | 2 + appveyor.yml | 13 ++-- tools/build-satelite-assembly.ps1 | 60 +++++++++++++++++++ tools/build-zip-archive.ps1 | 98 +++++++++++++++++++++++++++++++ tools/functions.ps1 | 30 ++++++++++ tools/generate-serializer.ps1 | 65 ++++++++++++++++++++ 6 files changed, 262 insertions(+), 6 deletions(-) create mode 100644 tools/build-satelite-assembly.ps1 create mode 100644 tools/build-zip-archive.ps1 create mode 100644 tools/functions.ps1 create mode 100644 tools/generate-serializer.ps1 diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index e56f0f284..e0203c038 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -11,6 +11,8 @@ v4.7.2 8.0 512 + true + $(MSBuildProjectDirectory)=. true diff --git a/appveyor.yml b/appveyor.yml index a7278701f..2fa3fe8f1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -28,11 +28,12 @@ after_test: - npm install codecov --save - ./node_modules/.bin/codecov -f coverage.xml - - del %APPVEYOR_BUILD_FOLDER%\OpenTween\bin\Debug\OpenTween.pdb - - 7z a OpenTween_dev-%APPVEYOR_BUILD_NUMBER%.zip %APPVEYOR_BUILD_FOLDER%\OpenTween\bin\Debug\* - -artifacts: - - name: OpenTween.zip - path: OpenTween_dev-$(APPVEYOR_BUILD_NUMBER).zip + - ps: | + $env:PATH = $env:PATH + ';C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\bin\Roslyn\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\' + $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\' + $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\' + $assemblyInfo = '.\OpenTween\Properties\AssemblyInfo.cs' + $destPath = 'OpenTween_dev-' + $env:APPVEYOR_BUILD_NUMBER + '.zip' + .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -AssemblyInfo $assemblyInfo -DestPath $destPath # vim: et fenc=utf-8 sts=2 sw=2 ts=2 diff --git a/tools/build-satelite-assembly.ps1 b/tools/build-satelite-assembly.ps1 new file mode 100644 index 000000000..d47bb37a1 --- /dev/null +++ b/tools/build-satelite-assembly.ps1 @@ -0,0 +1,60 @@ +# OpenTween - Client of Twitter +# Copyright (c) 2021 kim_upsilon (@kim_upsilon) +# All rights reserved. +# +# This file is part of OpenTween. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see , or write to +# the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +# Boston, MA 02110-1301, USA. + +# +# Reproducible Build に対応したサテライトアセンブリのビルド +# +# 使い方: +# .\tools\build-satelite-assembly.ps1 -ObjDir .\OpenTween\obj\Debug\ -Culture en -AssemblyInfo .\OpenTween\Properties\AssemblyInfo.cs -DestPath .\OpenTween\bin\Debug\en\OpenTween.resources.dll +# + +Param( + [Parameter(Mandatory = $true)][String] $ObjDir, + [Parameter(Mandatory = $true)][String] $Culture, + [Parameter(Mandatory = $true)][String] $AssemblyInfo, + [Parameter(Mandatory = $true)][String] $DestPath +) + +Set-StrictMode -Version 3.0 +$ErrorActionPreference = 'Stop' + +. .\tools\functions.ps1 + +Function Generate-AssemblyInfo() { + $tmpFile = New-TemporaryFile + $content = (Get-Content $AssemblyInfo) -replace "^\[assembly: AssemblyCulture.+$", "[assembly: AssemblyCulture(`"${Culture}`")]" + $content > $tmpFile.FullName + return $tmpFile.FullName +} + +Function Build-SateliteAssembly() { + $tmpAssemblyInfoPath = Generate-AssemblyInfo + try { + $resourcePaths = Get-ChildItem -Path $ObjDir -File -Filter "*.${Culture}.resources" + $cscOpts = "-utf8output -nologo -deterministic -target:library -debug- -optimize+ -out:${DestPath}" + $cscOpts += " " + ($resourcePaths | % { "-resource:$($_.FullName)" }) -join ' ' + Invoke-NativeCommand "csc $cscOpts $tmpAssemblyInfoPath" + } finally { + Remove-Item -Path $tmpAssemblyInfoPath + } +} + +Build-SateliteAssembly diff --git a/tools/build-zip-archive.ps1 b/tools/build-zip-archive.ps1 new file mode 100644 index 000000000..a2f8087f1 --- /dev/null +++ b/tools/build-zip-archive.ps1 @@ -0,0 +1,98 @@ +# OpenTween - Client of Twitter +# Copyright (c) 2021 kim_upsilon (@kim_upsilon) +# All rights reserved. +# +# This file is part of OpenTween. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see , or write to +# the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +# Boston, MA 02110-1301, USA. + +# +# Reproducible Build に対応した ZIP アーカイブのビルドを行うスクリプト +# +# 使い方: +# .\tools\build-zip-archive.ps1 -BinDir .\OpenTween\bin\Debug\ -ObjDir .\OpenTween\obj\Debug\ -AssemblyInfo .\OpenTween\Properties\AssemblyInfo.cs -DestPath OpenTween.zip +# + +Param( + [Parameter(Mandatory = $true)][String] $BinDir, + [Parameter(Mandatory = $true)][String] $ObjDir, + [Parameter(Mandatory = $true)][String] $AssemblyInfo, + [Parameter(Mandatory = $true)][String] $DestPath +) + +Set-StrictMode -Version 3.0 +$ErrorActionPreference = 'Stop' + +$assemblyName = "OpenTween" + +$exePath = Join-Path $BinDir "${assemblyName}.exe" +$sgenOpts = "/type:${assemblyName}.SettingAtIdList /type:${assemblyName}.SettingCommon /type:${assemblyName}.SettingLocal /type:${assemblyName}.SettingTabs" +$includeFiles = @( + "en\", + "Icons\", + "LICENSE", + "LICENSE.GPL-3", + "LICENSE.ja", + "LICENSE.LGPL-3", + "${assemblyName}.exe", + "${assemblyName}.exe.config", + "${assemblyName}.XmlSerializers.dll" +) + +. .\tools\functions.ps1 + +Function Generate-Serializer() { + # OpenTween.XmlSerializers.dll の生成 + .\tools\generate-serializer.ps1 -ExePath $exePath -SgenOpts $sgenOpts +} + +Function Build-SateliteAssembly([String] $Culture) { + # OpenTween.resources.dll の生成(カルチャ別) + $sateliteAssemblyPath = Join-Path $BinDir "${Culture}\${assemblyName}.resources.dll" + .\tools\build-satelite-assembly.ps1 -ObjDir $ObjDir -Culture $Culture -DestPath $sateliteAssemblyPath -AssemblyInfo $AssemblyInfo +} + +Function Get-SourceDateEpoch() { + # 本来 $unixEpoch は UTC で表さなければならないが、ZIP アーカイブには + # ローカルのタイムゾーンの日時でタイムスタンプが記録されるため、わざとタイムゾーンを指定していない。 + # これにより、生成される ZIP アーカイブには UTC での $sourceDateEpoch に相当する日時が記録されるようになる + $unixEpoch = Get-Date "1970/01/01 00:00:00" + $sourceDateUnixtime = [int](Invoke-NativeCommand "git log -1 --pretty=%ct") + $sourceDateEpoch = $unixEpoch.AddSeconds($sourceDateUnixtime) + return $sourceDateEpoch +} + +Function Reset-Timestamps([String[]] $Path, [DateTime] $Timestamp) { + # ZIP アーカイブに含めるファイルのタイムスタンプを揃える + Get-ChildItem $Path -Recurse | Set-ItemProperty -Name "LastWriteTime" -Value $Timestamp +} + +Function Build-Package([String[]] $Path, [String] $DestPath) { + Compress-Archive -Force -Path $Path -DestinationPath $DestPath +} + +Generate-Serializer +Build-SateliteAssembly -Culture en + +$includePaths = $includeFiles | % { Join-Path $BinDir $_ } +$timestamp = Get-SourceDateEpoch + +Reset-Timestamps -Path $includePaths -Timestamp $timestamp +Build-Package -Path $includePaths -DestPath $DestPath + +Write-Host +Write-Host "Build success!" +Get-FileHash -Algorithm SHA256 $destPath | Format-List diff --git a/tools/functions.ps1 b/tools/functions.ps1 new file mode 100644 index 000000000..83856cdff --- /dev/null +++ b/tools/functions.ps1 @@ -0,0 +1,30 @@ +# OpenTween - Client of Twitter +# Copyright (c) 2021 kim_upsilon (@kim_upsilon) +# All rights reserved. +# +# This file is part of OpenTween. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see , or write to +# the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +# Boston, MA 02110-1301, USA. + +Set-StrictMode -Version 3.0 +$ErrorActionPreference = 'Stop' + +Function Invoke-NativeCommand([String] $Command) { + Invoke-Expression -Command $Command + if ($LASTEXITCODE -ne 0) { + throw "Child process died with exit code: $LASTEXITCODE" + } +} diff --git a/tools/generate-serializer.ps1 b/tools/generate-serializer.ps1 new file mode 100644 index 000000000..577057eca --- /dev/null +++ b/tools/generate-serializer.ps1 @@ -0,0 +1,65 @@ +# OpenTween - Client of Twitter +# Copyright (c) 2021 kim_upsilon (@kim_upsilon) +# All rights reserved. +# +# This file is part of OpenTween. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation; either version 3 of the License, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see , or write to +# the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +# Boston, MA 02110-1301, USA. + +# +# Reproducible Build に対応した OpenTween.XmlSerializers.dll の生成を行うスクリプト +# +# 使い方: +# .\tools\generate-serializer.ps1 -ExePath ".\OpenTween\bin\Debug\OpenTween.exe" -SgenOpts "/type:OpenTween.SettingCommon" +# + +Param( + [Parameter(Mandatory = $true)][String] $ExePath, + [String] $SgenOpts = "" +) + +Set-StrictMode -Version 3.0 +$ErrorActionPreference = 'Stop' + +$binDir = Split-Path -Parent $ExePath +$exeName = Split-Path -Leaf $ExePath + +$dllName = $exeName -replace "\.exe$", ".XmlSerializers.dll" +$dllPath = Join-Path $binDir $dllName + +. .\tools\functions.ps1 + +Function Generate-Serializer() { + $tempDirName = "temp" + $tempDir = Join-Path $binDir $tempDirName + $tempExePath = Join-Path $tempDir $exeName + + # sgen は *.exe と同じディレクトリにソースコードを書き出すため、作業用のディレクトリを用意してビルドを実行する + Remove-Item -Recurse $tempDir -ErrorAction Ignore + New-Item -ItemType "directory" -Path $binDir -Name $tempDirName | Out-Null + Copy-Item $ExePath -Destination $tempDir + + # sgen が実行する C# コンパイラは Roslyn ではないため /deterministic オプションに対応していない。 + # sgen の /keep オプションによってソースコードと csc に渡すコマンドラインオプションが書き出されるため、これを使用して改めて Roslyn でコンパイルし直す + Invoke-NativeCommand "sgen /nologo /silent /keep $SgenOpts $tempExePath" + $cmdlinePath = Join-Path $tempDir "*.cmdline" + Invoke-NativeCommand "csc -nologo -warn:1 -deterministic $(Get-Content $cmdlinePath)" + + Copy-Item $(Join-Path $tempDir $dllName) -Destination $binDir + Remove-Item -Recurse $tempDir +} + +Generate-Serializer From b1f1e427edcbf70ca9cc4fccb31d9777db1f2992 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 6 Mar 2021 20:25:20 +0900 Subject: [PATCH 032/402] =?UTF-8?q?=E3=83=AA=E3=83=9D=E3=82=B8=E3=83=88?= =?UTF-8?q?=E3=83=AA=E3=81=AB=E3=82=BF=E3=82=B0=E3=81=8Cpush=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AFAppVeyor=E3=81=A7R?= =?UTF-8?q?elease=E3=83=93=E3=83=AB=E3=83=89=E3=82=92=E5=AE=9F=E8=A1=8C?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit これまで AppVeyor では Debug ビルドのみを実行していたが、Reproducible Build の 確認にも使えるようにするため Release ビルドも行われるようにした --- appveyor.yml | 49 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2fa3fe8f1..62f169cf0 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,10 +2,43 @@ version: 2.4.3.{build} os: Visual Studio 2019 -assembly_info: - patch: true - file: OpenTween\Properties\AssemblyInfo.cs - assembly_file_version: '{version}' +environment: + matrix: + - RELEASE_TAG: 'false' + - RELEASE_TAG: 'true' + +configuration: + - Debug + - Release + +matrix: + exclude: + - RELEASE_TAG: 'false' + configuration: Release + - RELEASE_TAG: 'true' + configuration: Debug + +for: + - # for dev build + matrix: + only: + - RELEASE_TAG: 'false' + skip_tags: true + assembly_info: + patch: true + file: OpenTween\Properties\AssemblyInfo.cs + assembly_version: '{version}' + artifacts: + - name: OpenTween.zip + path: OpenTween_dev-$(APPVEYOR_BUILD_NUMBER).zip + - # for release build + matrix: + only: + - RELEASE_TAG: 'true' + skip_non_tags: true + artifacts: + - name: OpenTween.zip + path: $(APPVEYOR_REPO_TAG_NAME).zip build: project: OpenTween.sln @@ -22,7 +55,7 @@ before_build: - choco install opencover.portable test_script: - - OpenCover.Console.exe -register -target:"%xunit20%\xunit.console.exe" -targetargs:".\OpenTween.Tests\bin\Debug\net472\OpenTween.Tests.dll -noshadow -appveyor" -filter:"+[OpenTween*]* -[OpenTween.Tests]*" -excludebyfile:"*.Designer.cs" -skipautoprops -hideskipped:All -returntargetcode -output:coverage.xml + - OpenCover.Console.exe -register -target:"%xunit20%\xunit.console.exe" -targetargs:".\OpenTween.Tests\bin\%CONFIGURATION%\net472\OpenTween.Tests.dll -noshadow -appveyor" -filter:"+[OpenTween*]* -[OpenTween.Tests]*" -excludebyfile:"*.Designer.cs" -skipautoprops -hideskipped:All -returntargetcode -output:coverage.xml after_test: - npm install codecov --save @@ -33,7 +66,11 @@ after_test: $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\' $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\' $assemblyInfo = '.\OpenTween\Properties\AssemblyInfo.cs' - $destPath = 'OpenTween_dev-' + $env:APPVEYOR_BUILD_NUMBER + '.zip' + if ($env:RELEASE_TAG -eq 'true') { + $destPath = $env:APPVEYOR_REPO_TAG_NAME + '.zip' + } else { + $destPath = 'OpenTween_dev-' + $env:APPVEYOR_BUILD_NUMBER + '.zip' + } .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -AssemblyInfo $assemblyInfo -DestPath $destPath # vim: et fenc=utf-8 sts=2 sw=2 ts=2 From 9f6b99fb2fb930d0409f7c5c9de99ad90984c3bc Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 22 Jan 2022 11:03:51 +0900 Subject: [PATCH 033/402] =?UTF-8?q?IMediaUploadService=E9=96=A2=E9=80=A3?= =?UTF-8?q?=E3=81=AE=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AE=E5=90=8D=E5=89=8D?= =?UTF-8?q?=E7=A9=BA=E9=96=93=E3=82=92=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Api/ImgurApi.cs | 80 ++++++++++++++++ OpenTween/Api/MobypictureApi.cs | 93 +++++++++++++++++++ OpenTween/MediaSelector.cs | 6 +- .../IMediaUploadService.cs | 2 +- .../Imgur.cs | 45 +-------- .../Mobypicture.cs | 61 +----------- .../TwitterPhoto.cs | 2 +- OpenTween/OpenTween.csproj | 10 +- OpenTween/Tween.cs | 1 + 9 files changed, 188 insertions(+), 112 deletions(-) create mode 100644 OpenTween/Api/ImgurApi.cs create mode 100644 OpenTween/Api/MobypictureApi.cs rename OpenTween/{Connection => MediaUploadServices}/IMediaUploadService.cs (98%) rename OpenTween/{Connection => MediaUploadServices}/Imgur.cs (72%) rename OpenTween/{Connection => MediaUploadServices}/Mobypicture.cs (65%) rename OpenTween/{Connection => MediaUploadServices}/TwitterPhoto.cs (99%) diff --git a/OpenTween/Api/ImgurApi.cs b/OpenTween/Api/ImgurApi.cs new file mode 100644 index 000000000..d5c39be68 --- /dev/null +++ b/OpenTween/Api/ImgurApi.cs @@ -0,0 +1,80 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2013 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using OpenTween.Connection; + +namespace OpenTween.Api +{ + public class ImgurApi + { + private readonly string clientId; + private readonly HttpClient http; + + private static readonly Uri UploadEndpoint = new Uri("https://api.imgur.com/3/image.xml"); + + public ImgurApi() + : this(ApplicationSettings.ImgurClientID) + { + } + + public ImgurApi(string clientId) + { + this.clientId = clientId; + this.http = Networking.CreateHttpClient(Networking.CreateHttpClientHandler()); + this.http.Timeout = Networking.UploadImageTimeout; + } + + public async Task UploadFileAsync(IMediaItem item, string title) + { + using var content = new MultipartFormDataContent(); + using var mediaStream = item.OpenRead(); + using var mediaContent = new StreamContent(mediaStream); + using var titleContent = new StringContent(title); + + content.Add(mediaContent, "image", item.Name); + content.Add(titleContent, "title"); + + using var request = new HttpRequestMessage(HttpMethod.Post, UploadEndpoint); + request.Headers.Authorization = new AuthenticationHeaderValue("Client-ID", this.clientId); + request.Content = content; + + using var response = await this.http.SendAsync(request) + .ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); + + using var stream = await response.Content.ReadAsStreamAsync() + .ConfigureAwait(false); + + return XDocument.Load(stream); + } + } +} diff --git a/OpenTween/Api/MobypictureApi.cs b/OpenTween/Api/MobypictureApi.cs new file mode 100644 index 000000000..7c286b150 --- /dev/null +++ b/OpenTween/Api/MobypictureApi.cs @@ -0,0 +1,93 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2014 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using OpenTween.Connection; + +namespace OpenTween.Api +{ + public class MobypictureApi + { + private readonly string apiKey; + private readonly HttpClient http; + + private static readonly Uri UploadEndpoint = new Uri("https://api.mobypicture.com/2.0/upload.xml"); + + private static readonly Uri OAuthRealm = new Uri("http://api.twitter.com/"); + private static readonly Uri AuthServiceProvider = new Uri("https://api.twitter.com/1.1/account/verify_credentials.json"); + + public MobypictureApi(TwitterApi twitterApi) + : this(ApplicationSettings.MobypictureKey, twitterApi) + { + } + + public MobypictureApi(string apiKey, TwitterApi twitterApi) + { + this.apiKey = apiKey; + + var handler = twitterApi.CreateOAuthEchoHandler(AuthServiceProvider, OAuthRealm); + this.http = Networking.CreateHttpClient(handler); + this.http.Timeout = Networking.UploadImageTimeout; + } + + /// + /// 画像のアップロードを行います + /// + /// + /// + public async Task UploadFileAsync(IMediaItem item, string message) + { + // 参照: http://developers.mobypicture.com/documentation/2-0/upload/ + + using var request = new HttpRequestMessage(HttpMethod.Post, UploadEndpoint); + using var multipart = new MultipartFormDataContent(); + request.Content = multipart; + + using var apiKeyContent = new StringContent(this.apiKey); + using var messageContent = new StringContent(message); + using var mediaStream = item.OpenRead(); + using var mediaContent = new StreamContent(mediaStream); + + multipart.Add(apiKeyContent, "key"); + multipart.Add(messageContent, "message"); + multipart.Add(mediaContent, "media", item.Name); + + using var response = await this.http.SendAsync(request) + .ConfigureAwait(false); + + var responseText = await response.Content.ReadAsStringAsync() + .ConfigureAwait(false); + + if (!response.IsSuccessStatusCode) + throw new WebApiException(response.StatusCode.ToString(), responseText); + + return XDocument.Parse(responseText); + } + } +} diff --git a/OpenTween/MediaSelector.cs b/OpenTween/MediaSelector.cs index f86474361..7c2224b6e 100644 --- a/OpenTween/MediaSelector.cs +++ b/OpenTween/MediaSelector.cs @@ -24,16 +24,16 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Drawing; using System.Data; +using System.Diagnostics.CodeAnalysis; +using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using OpenTween.Api.DataModel; -using OpenTween.Connection; -using System.Diagnostics.CodeAnalysis; +using OpenTween.MediaUploadServices; namespace OpenTween { diff --git a/OpenTween/Connection/IMediaUploadService.cs b/OpenTween/MediaUploadServices/IMediaUploadService.cs similarity index 98% rename from OpenTween/Connection/IMediaUploadService.cs rename to OpenTween/MediaUploadServices/IMediaUploadService.cs index 2929ec50b..c2133995f 100644 --- a/OpenTween/Connection/IMediaUploadService.cs +++ b/OpenTween/MediaUploadServices/IMediaUploadService.cs @@ -29,7 +29,7 @@ using System.Threading.Tasks; using OpenTween.Api.DataModel; -namespace OpenTween.Connection +namespace OpenTween.MediaUploadServices { /// /// Twitterでの画像の共有に使用できるサービスを表すインタフェース diff --git a/OpenTween/Connection/Imgur.cs b/OpenTween/MediaUploadServices/Imgur.cs similarity index 72% rename from OpenTween/Connection/Imgur.cs rename to OpenTween/MediaUploadServices/Imgur.cs index 38e62696c..54ff9acff 100644 --- a/OpenTween/Connection/Imgur.cs +++ b/OpenTween/MediaUploadServices/Imgur.cs @@ -23,16 +23,13 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Net.Http; -using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; -using System.Xml.Linq; +using OpenTween.Api; using OpenTween.Api.DataModel; -namespace OpenTween.Connection +namespace OpenTween.MediaUploadServices { public class Imgur : IMediaUploadService { @@ -139,43 +136,5 @@ public int GetReservedTextLength(int mediaCount) public void UpdateTwitterConfiguration(TwitterConfiguration config) => this.twitterConfig = config; - - public class ImgurApi - { - private readonly HttpClient http; - - private static readonly Uri UploadEndpoint = new Uri("https://api.imgur.com/3/image.xml"); - - public ImgurApi() - { - this.http = Networking.CreateHttpClient(Networking.CreateHttpClientHandler()); - this.http.Timeout = Networking.UploadImageTimeout; - } - - public async Task UploadFileAsync(IMediaItem item, string title) - { - using var content = new MultipartFormDataContent(); - using var mediaStream = item.OpenRead(); - using var mediaContent = new StreamContent(mediaStream); - using var titleContent = new StringContent(title); - - content.Add(mediaContent, "image", item.Name); - content.Add(titleContent, "title"); - - using var request = new HttpRequestMessage(HttpMethod.Post, UploadEndpoint); - request.Headers.Authorization = new AuthenticationHeaderValue("Client-ID", ApplicationSettings.ImgurClientID); - request.Content = content; - - using var response = await this.http.SendAsync(request) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - using var stream = await response.Content.ReadAsStreamAsync() - .ConfigureAwait(false); - - return XDocument.Load(stream); - } - } } } diff --git a/OpenTween/Connection/Mobypicture.cs b/OpenTween/MediaUploadServices/Mobypicture.cs similarity index 65% rename from OpenTween/Connection/Mobypicture.cs rename to OpenTween/MediaUploadServices/Mobypicture.cs index 931e233f2..ac983e44e 100644 --- a/OpenTween/Connection/Mobypicture.cs +++ b/OpenTween/MediaUploadServices/Mobypicture.cs @@ -23,20 +23,13 @@ using System; using System.Collections.Generic; -using System.IO; using System.Linq; -using System.Net; -using System.Net.Http; using System.Text; using System.Threading.Tasks; -using System.Windows.Forms; -using System.Xml; -using System.Xml.Linq; -using System.Xml.XPath; using OpenTween.Api; using OpenTween.Api.DataModel; -namespace OpenTween.Connection +namespace OpenTween.MediaUploadServices { public class Mobypicture : IMediaUploadService { @@ -148,57 +141,5 @@ public int GetReservedTextLength(int mediaCount) public void UpdateTwitterConfiguration(TwitterConfiguration config) => this.twitterConfig = config; - - public class MobypictureApi - { - private readonly HttpClient http; - - private static readonly Uri UploadEndpoint = new Uri("https://api.mobypicture.com/2.0/upload.xml"); - - private static readonly Uri OAuthRealm = new Uri("http://api.twitter.com/"); - private static readonly Uri AuthServiceProvider = new Uri("https://api.twitter.com/1.1/account/verify_credentials.json"); - - public MobypictureApi(TwitterApi twitterApi) - { - var handler = twitterApi.CreateOAuthEchoHandler(AuthServiceProvider, OAuthRealm); - - this.http = Networking.CreateHttpClient(handler); - this.http.Timeout = Networking.UploadImageTimeout; - } - - /// - /// 画像のアップロードを行います - /// - /// - /// - public async Task UploadFileAsync(IMediaItem item, string message) - { - // 参照: http://developers.mobypicture.com/documentation/2-0/upload/ - - using var request = new HttpRequestMessage(HttpMethod.Post, UploadEndpoint); - using var multipart = new MultipartFormDataContent(); - request.Content = multipart; - - using var apiKeyContent = new StringContent(ApplicationSettings.MobypictureKey); - using var messageContent = new StringContent(message); - using var mediaStream = item.OpenRead(); - using var mediaContent = new StreamContent(mediaStream); - - multipart.Add(apiKeyContent, "key"); - multipart.Add(messageContent, "message"); - multipart.Add(mediaContent, "media", item.Name); - - using var response = await this.http.SendAsync(request) - .ConfigureAwait(false); - - var responseText = await response.Content.ReadAsStringAsync() - .ConfigureAwait(false); - - if (!response.IsSuccessStatusCode) - throw new WebApiException(response.StatusCode.ToString(), responseText); - - return XDocument.Parse(responseText); - } - } } } diff --git a/OpenTween/Connection/TwitterPhoto.cs b/OpenTween/MediaUploadServices/TwitterPhoto.cs similarity index 99% rename from OpenTween/Connection/TwitterPhoto.cs rename to OpenTween/MediaUploadServices/TwitterPhoto.cs index ee1350b3b..5356f7be8 100644 --- a/OpenTween/Connection/TwitterPhoto.cs +++ b/OpenTween/MediaUploadServices/TwitterPhoto.cs @@ -37,7 +37,7 @@ using OpenTween.Api.DataModel; using OpenTween.Setting; -namespace OpenTween.Connection +namespace OpenTween.MediaUploadServices { public class TwitterPhoto : IMediaUploadService { diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index e0203c038..94bfe47fc 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -90,8 +90,10 @@ + + @@ -121,10 +123,10 @@ - - + + - + @@ -242,7 +244,7 @@ ListManage.cs - + Component diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 6171cc850..51289fe06 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -53,6 +53,7 @@ using OpenTween.Api; using OpenTween.Api.DataModel; using OpenTween.Connection; +using OpenTween.MediaUploadServices; using OpenTween.Models; using OpenTween.OpenTweenCustomControl; using OpenTween.Setting; From 4ee169f827fe15b829d3ece9a74314bbfeb637a3 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 22 Jan 2022 16:06:33 +0900 Subject: [PATCH 034/402] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=B3?= =?UTF-8?q?=E3=83=BC=E3=83=89=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Api/ImgurApiTest.cs | 151 ++++++++++++++++++ OpenTween.Tests/Api/MobypictureApiTest.cs | 92 +++++++++++ .../MediaUploadServices/ImgurTest.cs | 101 ++++++++++++ .../MediaUploadServices/MobypictureTest.cs | 99 ++++++++++++ OpenTween.Tests/TestUtils.cs | 3 + OpenTween/Api/ImgurApi.cs | 71 ++++++-- OpenTween/Api/MobypictureApi.cs | 56 +++++-- OpenTween/MediaUploadServices/Imgur.cs | 32 ++-- OpenTween/MediaUploadServices/Mobypicture.cs | 29 ++-- 9 files changed, 576 insertions(+), 58 deletions(-) create mode 100644 OpenTween.Tests/Api/ImgurApiTest.cs create mode 100644 OpenTween.Tests/Api/MobypictureApiTest.cs create mode 100644 OpenTween.Tests/MediaUploadServices/ImgurTest.cs create mode 100644 OpenTween.Tests/MediaUploadServices/MobypictureTest.cs diff --git a/OpenTween.Tests/Api/ImgurApiTest.cs b/OpenTween.Tests/Api/ImgurApiTest.cs new file mode 100644 index 000000000..a930d6efe --- /dev/null +++ b/OpenTween.Tests/Api/ImgurApiTest.cs @@ -0,0 +1,151 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween.Api +{ + public class ImgurApiTest + { + [Fact] + public async Task UploadFileAsync_Test() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + + mockHandler.Enqueue(x => + { + Assert.Equal(HttpMethod.Post, x.Method); + Assert.Equal(ImgurApi.UploadEndpoint, x.RequestUri); + + Assert.Equal("Client-ID", x.Headers.Authorization.Scheme); + Assert.Equal("fake_api_key", x.Headers.Authorization.Parameter); + + return new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent(@" + + aaaaaaa + てすと + + 1234567890 + image/png + false + 300 + 300 + 1000 + 0 + 0 + + false + +
+ + 0 + false + false + false + + 0 + + 0 + false + aaaaaaaaaaaaaaa + + https://i.imgur.com/aaaaaaa.png +"), + }; + }); + + var imgurApi = new ImgurApi("fake_api_key", http); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + var uploadedUrl = await imgurApi.UploadFileAsync(mediaItem, "てすと") + .ConfigureAwait(false); + Assert.Equal("https://i.imgur.com/aaaaaaa.png", uploadedUrl); + + Assert.Equal(0, mockHandler.QueueCount); + } + + [Fact] + public async Task UploadFileAsync_ErrorResponseTest() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + + mockHandler.Enqueue(x => + { + Assert.Equal(HttpMethod.Post, x.Method); + Assert.Equal(ImgurApi.UploadEndpoint, x.RequestUri); + + return new HttpResponseMessage(HttpStatusCode.BadRequest) + { + Content = new StringContent(@" + + No image data was sent to the upload api + /3/image.xml + POST +"), + }; + }); + + var imgurApi = new ImgurApi("fake_api_key", http); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + await Assert.ThrowsAsync( + () => imgurApi.UploadFileAsync(mediaItem, "てすと") + ); + + Assert.Equal(0, mockHandler.QueueCount); + } + + [Fact] + public async Task UploadFileAsync_InvalidResponseTest() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + + mockHandler.Enqueue(x => + { + Assert.Equal(HttpMethod.Post, x.Method); + Assert.Equal(ImgurApi.UploadEndpoint, x.RequestUri); + + return new HttpResponseMessage(HttpStatusCode.BadRequest) + { + Content = new StringContent("INVALID RESPONSE"), + }; + }); + + var imgurApi = new ImgurApi("fake_api_key", http); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + await Assert.ThrowsAsync( + () => imgurApi.UploadFileAsync(mediaItem, "てすと") + ); + + Assert.Equal(0, mockHandler.QueueCount); + } + } +} diff --git a/OpenTween.Tests/Api/MobypictureApiTest.cs b/OpenTween.Tests/Api/MobypictureApiTest.cs new file mode 100644 index 000000000..033be391a --- /dev/null +++ b/OpenTween.Tests/Api/MobypictureApiTest.cs @@ -0,0 +1,92 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween.Api +{ + public class MobypictureApiTest + { + [Fact] + public async Task UploadFileAsync_Test() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + + mockHandler.Enqueue(x => + { + Assert.Equal(HttpMethod.Post, x.Method); + Assert.Equal(MobypictureApi.UploadEndpoint, x.RequestUri); + + return new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent(@" + + + https://www.mobypicture.com/user/OpenTween/view/00000000 + +"), + }; + }); + + var mobypictureApi = new MobypictureApi("fake_api_key", http); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + var uploadedUrl = await mobypictureApi.UploadFileAsync(mediaItem, "てすと") + .ConfigureAwait(false); + Assert.Equal("https://www.mobypicture.com/user/OpenTween/view/00000000", uploadedUrl); + + Assert.Equal(0, mockHandler.QueueCount); + } + + [Fact] + public async Task UploadFileAsync_InvalidResponseTest() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + + mockHandler.Enqueue(x => + { + Assert.Equal(HttpMethod.Post, x.Method); + Assert.Equal(MobypictureApi.UploadEndpoint, x.RequestUri); + + return new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent("INVALID RESPONSE"), + }; + }); + + var mobypictureApi = new MobypictureApi("fake_api_key", http); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + await Assert.ThrowsAsync( + () => mobypictureApi.UploadFileAsync(mediaItem, "てすと") + ); + + Assert.Equal(0, mockHandler.QueueCount); + } + } +} diff --git a/OpenTween.Tests/MediaUploadServices/ImgurTest.cs b/OpenTween.Tests/MediaUploadServices/ImgurTest.cs new file mode 100644 index 000000000..59909fb4b --- /dev/null +++ b/OpenTween.Tests/MediaUploadServices/ImgurTest.cs @@ -0,0 +1,101 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; +using Moq; +using OpenTween.Api; +using OpenTween.Api.DataModel; +using Xunit; + +namespace OpenTween.MediaUploadServices +{ + public class ImgurTest + { + [Fact] + public async Task UploadAsync_Test() + { + var mockApi = new Mock(); + var imgurApi = mockApi.Object; + + var imgur = new Imgur(imgurApi, TwitterConfiguration.DefaultConfiguration()); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + + mockApi.Setup((x) => x.UploadFileAsync(mediaItem, "てすと")) + .ReturnsAsync("https://i.imgur.com/aaaaaaa.png"); + + var param = new PostStatusParams + { + Text = "てすと", + }; + await imgur.UploadAsync(new[] { mediaItem }, param); + + Assert.Equal("てすと https://i.imgur.com/aaaaaaa.png", param.Text); + } + + [Fact] + public async Task UploadAsync_ErrorResponseTest() + { + var mockApi = new Mock(); + var imgurApi = mockApi.Object; + + var imgur = new Imgur(imgurApi, TwitterConfiguration.DefaultConfiguration()); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + + mockApi.Setup((x) => x.UploadFileAsync(mediaItem, "てすと")) + .Throws(); + + var param = new PostStatusParams + { + Text = "てすと", + }; + await Assert.ThrowsAsync( + () => imgur.UploadAsync(new[] { mediaItem }, param) + ); + } + + [Fact] + public async Task UploadAsync_TimeoutTest() + { + var mockApi = new Mock(); + var imgurApi = mockApi.Object; + + var imgur = new Imgur(imgurApi, TwitterConfiguration.DefaultConfiguration()); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + + mockApi.Setup((x) => x.UploadFileAsync(mediaItem, "てすと")) + .Throws(); + + var param = new PostStatusParams + { + Text = "てすと", + }; + await Assert.ThrowsAsync( + () => imgur.UploadAsync(new[] { mediaItem }, param) + ); + } + } +} diff --git a/OpenTween.Tests/MediaUploadServices/MobypictureTest.cs b/OpenTween.Tests/MediaUploadServices/MobypictureTest.cs new file mode 100644 index 000000000..48c7e8e4c --- /dev/null +++ b/OpenTween.Tests/MediaUploadServices/MobypictureTest.cs @@ -0,0 +1,99 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Moq; +using OpenTween.Api; +using OpenTween.Api.DataModel; +using Xunit; + +namespace OpenTween.MediaUploadServices +{ + public class MobypictureTest + { + [Fact] + public async Task UploadAsync_Test() + { + var mockApi = new Mock(); + var mobypictureApi = mockApi.Object; + + var mobypicture = new Mobypicture(mobypictureApi, TwitterConfiguration.DefaultConfiguration()); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + + mockApi.Setup((x) => x.UploadFileAsync(mediaItem, "てすと")) + .ReturnsAsync("https://www.mobypicture.com/user/OpenTween/view/00000000"); + + var param = new PostStatusParams + { + Text = "てすと", + }; + await mobypicture.UploadAsync(new[] { mediaItem }, param); + + Assert.Equal("てすと https://www.mobypicture.com/user/OpenTween/view/00000000", param.Text); + } + + [Fact] + public async Task UploadAsync_ErrorResponseTest() + { + var mockApi = new Mock(); + var mobypictureApi = mockApi.Object; + + var mobypicture = new Mobypicture(mobypictureApi, TwitterConfiguration.DefaultConfiguration()); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + + mockApi.Setup((x) => x.UploadFileAsync(mediaItem, "てすと")) + .Throws(); + + var param = new PostStatusParams + { + Text = "てすと", + }; + await Assert.ThrowsAsync( + () => mobypicture.UploadAsync(new[] { mediaItem }, param) + ); + } + + [Fact] + public async Task UploadAsync_TimeoutTest() + { + var mockApi = new Mock(); + var mobypictureApi = mockApi.Object; + + var mobypicture = new Mobypicture(mobypictureApi, TwitterConfiguration.DefaultConfiguration()); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + + mockApi.Setup((x) => x.UploadFileAsync(mediaItem, "てすと")) + .Throws(); + + var param = new PostStatusParams + { + Text = "てすと", + }; + await Assert.ThrowsAsync( + () => mobypicture.UploadAsync(new[] { mediaItem }, param) + ); + } + } +} diff --git a/OpenTween.Tests/TestUtils.cs b/OpenTween.Tests/TestUtils.cs index aef4bcd65..210c19538 100644 --- a/OpenTween.Tests/TestUtils.cs +++ b/OpenTween.Tests/TestUtils.cs @@ -107,6 +107,9 @@ public static MemoryImage CreateDummyImage() } } + public static MemoryImageMediaItem CreateDummyMediaItem() + => new MemoryImageMediaItem(CreateDummyImage()); + public static void FireEvent(T control, string eventName) where T : Control => TestUtils.FireEvent(control, eventName, EventArgs.Empty); diff --git a/OpenTween/Api/ImgurApi.cs b/OpenTween/Api/ImgurApi.cs index d5c39be68..ee7eeb372 100644 --- a/OpenTween/Api/ImgurApi.cs +++ b/OpenTween/Api/ImgurApi.cs @@ -28,31 +28,74 @@ using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; +using System.Xml; using System.Xml.Linq; +using System.Xml.XPath; using OpenTween.Connection; namespace OpenTween.Api { - public class ImgurApi + public class ImgurApi : IImgurApi { private readonly string clientId; private readonly HttpClient http; - private static readonly Uri UploadEndpoint = new Uri("https://api.imgur.com/3/image.xml"); + public static readonly Uri UploadEndpoint = new Uri("https://api.imgur.com/3/image.xml"); public ImgurApi() - : this(ApplicationSettings.ImgurClientID) + : this(ApplicationSettings.ImgurClientID, null) { } - public ImgurApi(string clientId) + public ImgurApi(string clientId, HttpClient? http) { this.clientId = clientId; - this.http = Networking.CreateHttpClient(Networking.CreateHttpClientHandler()); - this.http.Timeout = Networking.UploadImageTimeout; + + if (http != null) + { + this.http = http; + } + else + { + this.http = Networking.CreateHttpClient(Networking.CreateHttpClientHandler()); + this.http.Timeout = Networking.UploadImageTimeout; + } + } + + public async Task UploadFileAsync(IMediaItem item, string title) + { + using var response = await this.SendRequestAsync(item, title) + .ConfigureAwait(false); + + var responseText = await response.Content.ReadAsStringAsync() + .ConfigureAwait(false); + + XDocument responseXml; + try + { + responseXml = XDocument.Parse(responseText); + } + catch (XmlException ex) + { + var errorMessage = response.IsSuccessStatusCode ? "Invalid response" : response.StatusCode.ToString(); + throw new WebApiException("Err:" + errorMessage, responseText, ex); + } + + var imageElm = responseXml.Element("data"); + if (imageElm?.Attribute("success")?.Value != "1") + { + var errorMessage = imageElm?.Element("error")?.Value ?? "Invalid response"; + throw new WebApiException("Err:" + errorMessage, responseText); + } + + var imageUrl = responseXml.XPathSelectElement("/data/link")?.Value; + if (imageUrl == null) + throw new WebApiException("Err:Invalid response", responseText); + + return imageUrl.Trim(); } - public async Task UploadFileAsync(IMediaItem item, string title) + private async Task SendRequestAsync(IMediaItem item, string title) { using var content = new MultipartFormDataContent(); using var mediaStream = item.OpenRead(); @@ -66,15 +109,13 @@ public async Task UploadFileAsync(IMediaItem item, string title) request.Headers.Authorization = new AuthenticationHeaderValue("Client-ID", this.clientId); request.Content = content; - using var response = await this.http.SendAsync(request) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - using var stream = await response.Content.ReadAsStreamAsync() + return await this.http.SendAsync(request) .ConfigureAwait(false); - - return XDocument.Load(stream); } } + + public interface IImgurApi + { + Task UploadFileAsync(IMediaItem item, string title); + } } diff --git a/OpenTween/Api/MobypictureApi.cs b/OpenTween/Api/MobypictureApi.cs index 7c286b150..423e65fa2 100644 --- a/OpenTween/Api/MobypictureApi.cs +++ b/OpenTween/Api/MobypictureApi.cs @@ -27,17 +27,19 @@ using System.Net.Http; using System.Text; using System.Threading.Tasks; +using System.Xml; using System.Xml.Linq; +using System.Xml.XPath; using OpenTween.Connection; namespace OpenTween.Api { - public class MobypictureApi + public class MobypictureApi : IMobypictureApi { private readonly string apiKey; private readonly HttpClient http; - private static readonly Uri UploadEndpoint = new Uri("https://api.mobypicture.com/2.0/upload.xml"); + public static readonly Uri UploadEndpoint = new Uri("https://api.mobypicture.com/2.0/upload.xml"); private static readonly Uri OAuthRealm = new Uri("http://api.twitter.com/"); private static readonly Uri AuthServiceProvider = new Uri("https://api.twitter.com/1.1/account/verify_credentials.json"); @@ -56,12 +58,45 @@ public MobypictureApi(string apiKey, TwitterApi twitterApi) this.http.Timeout = Networking.UploadImageTimeout; } + public MobypictureApi(string apiKey, HttpClient http) + { + this.apiKey = apiKey; + this.http = http; + } + /// /// 画像のアップロードを行います /// + /// /// /// - public async Task UploadFileAsync(IMediaItem item, string message) + public async Task UploadFileAsync(IMediaItem item, string message) + { + using var response = await this.SendRequestAsync(item, message) + .ConfigureAwait(false); + + var responseText = await response.Content.ReadAsStringAsync() + .ConfigureAwait(false); + + XDocument responseXml; + try + { + responseXml = XDocument.Parse(responseText); + } + catch (XmlException ex) + { + var errorMessage = response.IsSuccessStatusCode ? "Invalid response" : response.StatusCode.ToString(); + throw new WebApiException("Err:" + errorMessage, responseText, ex); + } + + var imageUrlElm = responseXml.XPathSelectElement("/rsp/media/mediaurl"); + if (imageUrlElm == null) + throw new WebApiException("Invalid API response", responseText); + + return imageUrlElm.Value.Trim(); + } + + private async Task SendRequestAsync(IMediaItem item, string message) { // 参照: http://developers.mobypicture.com/documentation/2-0/upload/ @@ -78,16 +113,13 @@ public async Task UploadFileAsync(IMediaItem item, string message) multipart.Add(messageContent, "message"); multipart.Add(mediaContent, "media", item.Name); - using var response = await this.http.SendAsync(request) - .ConfigureAwait(false); - - var responseText = await response.Content.ReadAsStringAsync() + return await this.http.SendAsync(request) .ConfigureAwait(false); - - if (!response.IsSuccessStatusCode) - throw new WebApiException(response.StatusCode.ToString(), responseText); - - return XDocument.Parse(responseText); } } + + public interface IMobypictureApi + { + Task UploadFileAsync(IMediaItem item, string message); + } } diff --git a/OpenTween/MediaUploadServices/Imgur.cs b/OpenTween/MediaUploadServices/Imgur.cs index 54ff9acff..fe0402a9c 100644 --- a/OpenTween/MediaUploadServices/Imgur.cs +++ b/OpenTween/MediaUploadServices/Imgur.cs @@ -48,15 +48,19 @@ public class Imgur : IMediaUploadService ".xcf", }; - private readonly ImgurApi imgurApi; + private readonly IImgurApi imgurApi; private TwitterConfiguration twitterConfig; public Imgur(TwitterConfiguration twitterConfig) + : this(new ImgurApi(), twitterConfig) { - this.twitterConfig = twitterConfig; + } - this.imgurApi = new ImgurApi(); + public Imgur(IImgurApi imgurApi, TwitterConfiguration twitterConfig) + { + this.imgurApi = imgurApi; + this.twitterConfig = twitterConfig; } public int MaxMediaCount => 1; @@ -104,31 +108,19 @@ public async Task UploadAsync(IMediaItem[] mediaItems, PostSta if (!item.Exists) throw new ArgumentException("Err:Media not found."); - XDocument xml; try { - xml = await this.imgurApi.UploadFileAsync(item, postParams.Text) + var imageUrl = await this.imgurApi.UploadFileAsync(item, postParams.Text) .ConfigureAwait(false); - } - catch (HttpRequestException ex) - { - throw new WebApiException("Err:" + ex.Message, ex); + + postParams.Text += " " + imageUrl; + + return postParams; } catch (OperationCanceledException ex) { throw new WebApiException("Err:Timeout", ex); } - - var imageElm = xml.Element("data"); - - if (imageElm.Attribute("success").Value != "1") - throw new WebApiException("Err:" + imageElm.Attribute("status").Value); - - var imageUrl = imageElm.Element("link").Value; - - postParams.Text += " " + imageUrl.Trim(); - - return postParams; } public int GetReservedTextLength(int mediaCount) diff --git a/OpenTween/MediaUploadServices/Mobypicture.cs b/OpenTween/MediaUploadServices/Mobypicture.cs index ac983e44e..792208c12 100644 --- a/OpenTween/MediaUploadServices/Mobypicture.cs +++ b/OpenTween/MediaUploadServices/Mobypicture.cs @@ -68,15 +68,19 @@ public class Mobypicture : IMediaUploadService ".3gp", }; - private readonly MobypictureApi mobypictureApi; + private readonly IMobypictureApi mobypictureApi; private TwitterConfiguration twitterConfig; public Mobypicture(Twitter twitter, TwitterConfiguration twitterConfig) + : this(new MobypictureApi(twitter.Api), twitterConfig) { - this.twitterConfig = twitterConfig ?? throw new ArgumentNullException(nameof(twitterConfig)); + } - this.mobypictureApi = new MobypictureApi(twitter.Api); + public Mobypicture(IMobypictureApi mobypictureApi, TwitterConfiguration twitterConfig) + { + this.mobypictureApi = mobypictureApi; + this.twitterConfig = twitterConfig ?? throw new ArgumentNullException(nameof(twitterConfig)); } public int MaxMediaCount => 1; @@ -124,16 +128,19 @@ public async Task UploadAsync(IMediaItem[] mediaItems, PostSta if (!item.Exists) throw new ArgumentException("Err:Media not found."); - var xml = await this.mobypictureApi.UploadFileAsync(item, postParams.Text) - .ConfigureAwait(false); - - var imageUrlElm = xml.XPathSelectElement("/rsp/media/mediaurl"); - if (imageUrlElm == null) - throw new WebApiException("Invalid API response", xml.ToString()); + try + { + var imageUrl = await this.mobypictureApi.UploadFileAsync(item, postParams.Text) + .ConfigureAwait(false); - postParams.Text += " " + imageUrlElm.Value.Trim(); + postParams.Text += " " + imageUrl; - return postParams; + return postParams; + } + catch (OperationCanceledException ex) + { + throw new WebApiException("Err:Timeout", ex); + } } public int GetReservedTextLength(int mediaCount) From fc6f5d7236e7368cf97c13c04c72f2b4041b2d8b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 22 Jan 2022 21:19:06 +0900 Subject: [PATCH 035/402] =?UTF-8?q?Instagram=E3=81=AE=E3=82=B5=E3=83=A0?= =?UTF-8?q?=E3=83=8D=E3=82=A4=E3=83=AB=E3=82=92=E8=A1=A8=E7=A4=BA=E3=81=99?= =?UTF-8?q?=E3=82=8BURL=E3=81=AE=E3=83=91=E3=82=BF=E3=83=BC=E3=83=B3?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Thumbnail/ThumbnailGeneratorTest.cs | 50 +++++++++++++++++++ OpenTween/Resources/ChangeLog.txt | 1 + .../Services/SimpleThumbnailService.cs | 7 ++- OpenTween/Thumbnail/ThumbnailGenerator.cs | 11 ++-- 4 files changed, 65 insertions(+), 4 deletions(-) create mode 100644 OpenTween.Tests/Thumbnail/ThumbnailGeneratorTest.cs diff --git a/OpenTween.Tests/Thumbnail/ThumbnailGeneratorTest.cs b/OpenTween.Tests/Thumbnail/ThumbnailGeneratorTest.cs new file mode 100644 index 000000000..0c61bd71f --- /dev/null +++ b/OpenTween.Tests/Thumbnail/ThumbnailGeneratorTest.cs @@ -0,0 +1,50 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween.Thumbnail +{ + public class ThumbnailGeneratorTest + { + [Theory] + [InlineData("https://www.instagram.com/p/aaaaaaaaaaa/", "aaaaaaaaaaa")] + [InlineData("http://www.instagram.com/p/aaaaaaaaaaa/", "aaaaaaaaaaa")] + [InlineData("https://i.instagram.com/p/aaaaaaaaaaa/", "aaaaaaaaaaa")] + [InlineData("https://instagram.com/p/aaaaaaaaaaa/", "aaaaaaaaaaa")] + [InlineData("https://instagr.am/p/aaaaaaaaaaa/", "aaaaaaaaaaa")] + [InlineData("https://www.instagram.com/hogehoge/p/aaaaaaaaaaa/", "aaaaaaaaaaa")] // ユーザー名付き + [InlineData("https://www.instagram.com/p/aaaaaaaaaaa/?utm_medium=copy_link", "aaaaaaaaaaa")] // トラッキングパラメータ付き + [InlineData("https://www.instagram.com/hogehoge/", null)] // プロフィールページ + public void InstagramPattern_IsMatchTest(string testUrl, string expected) + { + var match = ThumbnailGenerator.InstagramPattern.Match(testUrl); + + var matchedMediaId = match.Success ? match.Groups["mediaId"].Value : null; + Assert.Equal(expected, matchedMediaId); + } + } +} diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 75b85ffef..6bc611b27 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Ver 2.4.4-dev(2019/xx/xx) * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 + * CHG: Instagramのサムネイルを表示するURLのパターンを追加 * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) diff --git a/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs b/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs index 8de0cd5ee..6b9d316f1 100644 --- a/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs @@ -48,8 +48,13 @@ public SimpleThumbnailService(string pattern, string replacement) } public SimpleThumbnailService(string pattern, string replacement, string? file_replacement) + : this(new Regex(pattern, RegexOptions.IgnoreCase), replacement, file_replacement) { - this.regex = new Regex(pattern, RegexOptions.IgnoreCase); + } + + public SimpleThumbnailService(Regex regex, string replacement, string? file_replacement) + { + this.regex = regex; this.thumb_replacement = replacement; this.fullsize_replacement = file_replacement; } diff --git a/OpenTween/Thumbnail/ThumbnailGenerator.cs b/OpenTween/Thumbnail/ThumbnailGenerator.cs index e84e4733c..74b93ec2d 100644 --- a/OpenTween/Thumbnail/ThumbnailGenerator.cs +++ b/OpenTween/Thumbnail/ThumbnailGenerator.cs @@ -36,6 +36,11 @@ namespace OpenTween.Thumbnail { class ThumbnailGenerator { + public static readonly Regex InstagramPattern = new Regex( + @"^https?://(?:instagram.com|instagr\.am|i\.instagram\.com|www\.instagram\.com)/([^/]+/)?p/(?[^/]+)/(\?.*)?$", + RegexOptions.IgnoreCase + ); + public static List Services { get; protected set; } internal static ImgAzyobuziNet ImgAzyobuziNetInstance { get; private set; } = null!; @@ -132,9 +137,9 @@ public static void InitializeGenerator() // Instagram new SimpleThumbnailService( - @"^https?://(?:instagram.com|instagr\.am|i\.instagram\.com|www\.instagram\.com)/p/.+/", - "${0}media/?size=m", - "${0}media/?size=l"), + InstagramPattern, + "https://www.instagram.com/p/${mediaId}/media/?size=m", + "https://www.instagram.com/p/${mediaId}/media/?size=l"), // Foursquare new FoursquareCheckin(), From 7836bc52c192ee12dc22159a4ef0ad044044ef9d Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 17 Jan 2022 00:17:20 +0900 Subject: [PATCH 036/402] =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AB=E5=9F=8B=E3=82=81?= =?UTF-8?q?=E8=BE=BC=E3=82=80API=E3=82=AD=E3=83=BC=E3=81=AE=E6=9A=97?= =?UTF-8?q?=E5=8F=B7=E5=8C=96=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Api/BitlyApiTest.cs | 26 +- OpenTween.Tests/Api/ImgurApiTest.cs | 21 +- .../Api/MicrosoftTranslatorApiTest.cs | 29 ++- OpenTween.Tests/Api/MobypictureApiTest.cs | 21 +- OpenTween.Tests/Api/TwitterApiTest.cs | 100 ++++---- OpenTween.Tests/ApiKeyTest.cs | 115 +++++++++ .../Connection/OAuthUtilityTest.cs | 10 +- .../Connection/TwitterApiConnectionTest.cs | 24 +- OpenTween.Tests/MediaSelectorTest.cs | 43 +++- .../Services/FoursquareCheckinTest.cs | 34 ++- .../Thumbnail/Services/TinamiTest.cs | 15 +- .../Thumbnail/Services/TumblrTest.cs | 22 +- OpenTween.Tests/TwitterTest.cs | 139 +++++----- OpenTween/Api/BitlyApi.cs | 20 +- OpenTween/Api/ImgurApi.cs | 11 +- OpenTween/Api/MicrosoftTranslatorApi.cs | 19 +- OpenTween/Api/MobypictureApi.cs | 11 +- OpenTween/Api/TwitterApi.cs | 11 +- OpenTween/ApiKey.cs | 240 ++++++++++++++++++ OpenTween/ApplicationSettings.cs | 41 ++- OpenTween/Bing.cs | 7 +- OpenTween/Connection/OAuthEchoHandler.cs | 2 +- OpenTween/Connection/OAuthHandler.cs | 6 +- OpenTween/Connection/OAuthUtility.cs | 10 +- OpenTween/Connection/TwitterApiConnection.cs | 42 +-- OpenTween/OpenTween.csproj | 1 + .../Thumbnail/Services/FoursquareCheckin.cs | 28 +- OpenTween/Thumbnail/Services/Tinami.cs | 19 +- OpenTween/Thumbnail/Services/Tumblr.cs | 15 +- OpenTween/Tween.cs | 2 +- OpenTween/TweetDetailsView.cs | 2 +- OpenTween/Twitter.cs | 4 - 32 files changed, 819 insertions(+), 271 deletions(-) create mode 100644 OpenTween.Tests/ApiKeyTest.cs create mode 100644 OpenTween/ApiKey.cs diff --git a/OpenTween.Tests/Api/BitlyApiTest.cs b/OpenTween.Tests/Api/BitlyApiTest.cs index afed8d04a..b40a3ea2b 100644 --- a/OpenTween.Tests/Api/BitlyApiTest.cs +++ b/OpenTween.Tests/Api/BitlyApiTest.cs @@ -38,7 +38,7 @@ public async Task ShortenAsync_OAuth2Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - var bitly = new BitlyApi(http); + var bitly = new BitlyApi(ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret"), http); mockHandler.Enqueue(x => { @@ -72,7 +72,7 @@ public async Task ShortenAsync_LegacyApiKeyTest() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - var bitly = new BitlyApi(http); + var bitly = new BitlyApi(ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret"), http); mockHandler.Enqueue(x => { @@ -108,7 +108,7 @@ public async Task GetAccessTokenAsync_Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - var bitly = new BitlyApi(http); + var bitly = new BitlyApi(ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret"), http); mockHandler.Enqueue(async x => { @@ -117,8 +117,10 @@ public async Task GetAccessTokenAsync_Test() x.RequestUri.GetLeftPart(UriPartial.Path)); Assert.Equal("Basic", x.Headers.Authorization.Scheme); - Assert.Equal(ApplicationSettings.BitlyClientId + ":" + ApplicationSettings.BitlyClientSecret, - Encoding.UTF8.GetString(Convert.FromBase64String(x.Headers.Authorization.Parameter))); + Assert.Equal( + Convert.ToBase64String(Encoding.UTF8.GetBytes("fake_client_id:fake_client_secret")), + x.Headers.Authorization.Parameter + ); var body = await x.Content.ReadAsStringAsync() .ConfigureAwait(false); @@ -146,7 +148,7 @@ public async Task GetAccessTokenAsync_ErrorResponseTest() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - var bitly = new BitlyApi(http); + var bitly = new BitlyApi(ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret"), http); mockHandler.Enqueue(x => { @@ -161,5 +163,17 @@ await Assert.ThrowsAsync(() => bitly.GetAccessTokenAsync("hogeh Assert.Equal(0, mockHandler.QueueCount); } + + [Fact] + public async Task GetAccessTokenAsync_ApiKeyErrorTest() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + var bitly = new BitlyApi(ApiKey.Create("%e%INVALID_API_KEY"), ApiKey.Create("%e%INVALID_API_KEY"), http); + + await Assert.ThrowsAsync( + () => bitly.GetAccessTokenAsync("hogehoge", "tetete") + ); + } } } diff --git a/OpenTween.Tests/Api/ImgurApiTest.cs b/OpenTween.Tests/Api/ImgurApiTest.cs index a930d6efe..de9a13995 100644 --- a/OpenTween.Tests/Api/ImgurApiTest.cs +++ b/OpenTween.Tests/Api/ImgurApiTest.cs @@ -82,7 +82,7 @@ public async Task UploadFileAsync_Test() }; }); - var imgurApi = new ImgurApi("fake_api_key", http); + var imgurApi = new ImgurApi(ApiKey.Create("fake_api_key"), http); using var mediaItem = TestUtils.CreateDummyMediaItem(); var uploadedUrl = await imgurApi.UploadFileAsync(mediaItem, "てすと") .ConfigureAwait(false); @@ -113,7 +113,7 @@ public async Task UploadFileAsync_ErrorResponseTest() }; }); - var imgurApi = new ImgurApi("fake_api_key", http); + var imgurApi = new ImgurApi(ApiKey.Create("fake_api_key"), http); using var mediaItem = TestUtils.CreateDummyMediaItem(); await Assert.ThrowsAsync( () => imgurApi.UploadFileAsync(mediaItem, "てすと") @@ -139,7 +139,22 @@ public async Task UploadFileAsync_InvalidResponseTest() }; }); - var imgurApi = new ImgurApi("fake_api_key", http); + var imgurApi = new ImgurApi(ApiKey.Create("fake_api_key"), http); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + await Assert.ThrowsAsync( + () => imgurApi.UploadFileAsync(mediaItem, "てすと") + ); + + Assert.Equal(0, mockHandler.QueueCount); + } + + [Fact] + public async Task UploadFileAsync_ApiKeyErrorTest() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + + var imgurApi = new ImgurApi(ApiKey.Create("%e%INVALID_API_KEY"), http); using var mediaItem = TestUtils.CreateDummyMediaItem(); await Assert.ThrowsAsync( () => imgurApi.UploadFileAsync(mediaItem, "てすと") diff --git a/OpenTween.Tests/Api/MicrosoftTranslatorApiTest.cs b/OpenTween.Tests/Api/MicrosoftTranslatorApiTest.cs index 84e269631..2812623a3 100644 --- a/OpenTween.Tests/Api/MicrosoftTranslatorApiTest.cs +++ b/OpenTween.Tests/Api/MicrosoftTranslatorApiTest.cs @@ -42,7 +42,7 @@ public async Task TranslateAsync_Test() using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - var mock = new Mock(http); + var mock = new Mock(ApiKey.Create("fake_api_key"), http); mock.Setup(x => x.GetAccessTokenAsync()) .ReturnsAsync(("1234abcd", TimeSpan.FromSeconds(1000))); @@ -94,10 +94,27 @@ public async Task TranslateAsync_Test() Assert.Equal(0, mockHandler.QueueCount); } + [Fact] + public async Task TranslateAsync_ApiKeyErrorTest() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + + var mock = new Mock(ApiKey.Create("%e%INVALID_API_KEY"), http); + var translateApi = mock.Object; + + await Assert.ThrowsAsync( + () => translateApi.TranslateAsync("hogehoge", langTo: "ja", langFrom: "en") + ); + + mock.Verify(x => x.GetAccessTokenAsync(), Times.Never()); + Assert.Equal(0, mockHandler.QueueCount); + } + [Fact] public async Task UpdateAccessTokenIfExpired_FirstCallTest() { - var mock = new Mock(); + var mock = new Mock(ApiKey.Create("fake_api_key"), null); mock.Setup(x => x.GetAccessTokenAsync()) .ReturnsAsync(("1234abcd", TimeSpan.FromSeconds(1000))); @@ -116,7 +133,7 @@ await translateApi.UpdateAccessTokenIfExpired() [Fact] public async Task UpdateAccessTokenIfExpired_NotExpiredTest() { - var mock = new Mock(); + var mock = new Mock(ApiKey.Create("fake_api_key"), null); var translateApi = mock.Object; translateApi.AccessToken = "1234abcd"; @@ -132,7 +149,7 @@ await translateApi.UpdateAccessTokenIfExpired() [Fact] public async Task UpdateAccessTokenIfExpired_ExpiredTest() { - var mock = new Mock(); + var mock = new Mock(ApiKey.Create("fake_api_key"), null); mock.Setup(x => x.GetAccessTokenAsync()) .ReturnsAsync(("5678efgh", TimeSpan.FromSeconds(1000))); @@ -155,7 +172,7 @@ public async Task GetAccessTokenAsync_Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - var translateApi = new MicrosoftTranslatorApi(http); + var translateApi = new MicrosoftTranslatorApi(ApiKey.Create("fake_api_key"), http); mockHandler.Enqueue(x => { @@ -163,7 +180,7 @@ public async Task GetAccessTokenAsync_Test() Assert.Equal(MicrosoftTranslatorApi.IssueTokenEndpoint, x.RequestUri); var keyHeader = x.Headers.First(y => y.Key == "Ocp-Apim-Subscription-Key"); - Assert.Equal(ApplicationSettings.TranslatorSubscriptionKey, keyHeader.Value.Single()); + Assert.Equal("fake_api_key", keyHeader.Value.Single()); return new HttpResponseMessage(HttpStatusCode.OK) { diff --git a/OpenTween.Tests/Api/MobypictureApiTest.cs b/OpenTween.Tests/Api/MobypictureApiTest.cs index 033be391a..cbde60a5b 100644 --- a/OpenTween.Tests/Api/MobypictureApiTest.cs +++ b/OpenTween.Tests/Api/MobypictureApiTest.cs @@ -30,7 +30,7 @@ namespace OpenTween.Api { - public class MobypictureApiTest + public class MobypictureApiText { [Fact] public async Task UploadFileAsync_Test() @@ -54,7 +54,7 @@ public async Task UploadFileAsync_Test() }; }); - var mobypictureApi = new MobypictureApi("fake_api_key", http); + var mobypictureApi = new MobypictureApi(ApiKey.Create("fake_api_key"), http); using var mediaItem = TestUtils.CreateDummyMediaItem(); var uploadedUrl = await mobypictureApi.UploadFileAsync(mediaItem, "てすと") .ConfigureAwait(false); @@ -80,7 +80,22 @@ public async Task UploadFileAsync_InvalidResponseTest() }; }); - var mobypictureApi = new MobypictureApi("fake_api_key", http); + var mobypictureApi = new MobypictureApi(ApiKey.Create("fake_api_key"), http); + using var mediaItem = TestUtils.CreateDummyMediaItem(); + await Assert.ThrowsAsync( + () => mobypictureApi.UploadFileAsync(mediaItem, "てすと") + ); + + Assert.Equal(0, mockHandler.QueueCount); + } + + [Fact] + public async Task UploadFileAsync_ApiKeyErrorTest() + { + using var mockHandler = new HttpMessageHandlerMock(); + using var http = new HttpClient(mockHandler); + + var mobypictureApi = new MobypictureApi(ApiKey.Create("%e%INVALID_API_KEY"), http); using var mediaItem = TestUtils.CreateDummyMediaItem(); await Assert.ThrowsAsync( () => mobypictureApi.UploadFileAsync(mediaItem, "てすと") diff --git a/OpenTween.Tests/Api/TwitterApiTest.cs b/OpenTween.Tests/Api/TwitterApiTest.cs index 6bd0d1ee9..026ec4b74 100644 --- a/OpenTween.Tests/Api/TwitterApiTest.cs +++ b/OpenTween.Tests/Api/TwitterApiTest.cs @@ -51,7 +51,7 @@ private void MyCommonSetup() [Fact] public void Initialize_Test() { - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); Assert.Null(twitterApi.apiConnection); twitterApi.Initialize("*** AccessToken ***", "*** AccessSecret ***", userId: 100L, screenName: "hogehoge"); @@ -100,7 +100,7 @@ public async Task StatusesHomeTimeline_Test() ) .ReturnsAsync(Array.Empty()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.StatusesHomeTimeline(200, maxId: 900L, sinceId: 100L) @@ -128,7 +128,7 @@ public async Task StatusesMentionsTimeline_Test() ) .ReturnsAsync(Array.Empty()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.StatusesMentionsTimeline(200, maxId: 900L, sinceId: 100L) @@ -158,7 +158,7 @@ public async Task StatusesUserTimeline_Test() ) .ReturnsAsync(Array.Empty()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.StatusesUserTimeline("twitterapi", count: 200, maxId: 900L, sinceId: 100L) @@ -184,7 +184,7 @@ public async Task StatusesShow_Test() ) .ReturnsAsync(new TwitterStatus { Id = 100L }); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.StatusesShow(statusId: 100L) @@ -214,7 +214,7 @@ public async Task StatusesUpdate_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterStatus())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.StatusesUpdate("hogehoge", replyToId: 100L, mediaIds: new[] { 10L, 20L }, @@ -243,7 +243,7 @@ public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest() ) .ReturnsAsync(LazyJson.Create(new TwitterStatus())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.StatusesUpdate("hogehoge", replyToId: null, mediaIds: null, excludeReplyUserIds: Array.Empty()) @@ -264,7 +264,7 @@ public async Task StatusesDestroy_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L })); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.StatusesDestroy(statusId: 100L) @@ -290,7 +290,7 @@ public async Task StatusesRetweet_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterStatus())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.StatusesRetweet(100L) @@ -322,7 +322,7 @@ public async Task SearchTweets_Test() ) .ReturnsAsync(new TwitterSearchResult()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.SearchTweets("from:twitterapi", "en", count: 200, maxId: 900L, sinceId: 100L) @@ -347,7 +347,7 @@ public async Task ListsOwnerships_Test() ) .ReturnsAsync(new TwitterLists()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsOwnerships("twitterapi", cursor: -1L, count: 100) @@ -372,7 +372,7 @@ public async Task ListsSubscriptions_Test() ) .ReturnsAsync(new TwitterLists()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsSubscriptions("twitterapi", cursor: -1L, count: 100) @@ -398,7 +398,7 @@ public async Task ListsMemberships_Test() ) .ReturnsAsync(new TwitterLists()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsMemberships("twitterapi", cursor: -1L, count: 100, filterToOwnedLists: true) @@ -422,7 +422,7 @@ public async Task ListsCreate_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterList())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsCreate("hogehoge", description: "aaaa", @private: true) @@ -448,7 +448,7 @@ public async Task ListsUpdate_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterList())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsUpdate(12345L, name: "hogehoge", description: "aaaa", @private: true) @@ -471,7 +471,7 @@ public async Task ListsDestroy_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterList())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsDestroy(12345L) @@ -502,7 +502,7 @@ public async Task ListsStatuses_Test() ) .ReturnsAsync(Array.Empty()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsStatuses(12345L, count: 200, maxId: 900L, sinceId: 100L, includeRTs: true) @@ -529,7 +529,7 @@ public async Task ListsMembers_Test() ) .ReturnsAsync(new TwitterUsers()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsMembers(12345L, cursor: -1) @@ -556,7 +556,7 @@ public async Task ListsMembersShow_Test() ) .ReturnsAsync(new TwitterUser()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsMembersShow(12345L, "twitterapi") @@ -582,7 +582,7 @@ public async Task ListsMembersCreate_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUser())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsMembersCreate(12345L, "twitterapi") @@ -609,7 +609,7 @@ public async Task ListsMembersDestroy_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUser())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ListsMembersDestroy(12345L, "twitterapi") @@ -634,7 +634,7 @@ public async Task DirectMessagesEventsList_Test() ) .ReturnsAsync(new TwitterMessageEventList()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.DirectMessagesEventsList(count: 50, cursor: "12345abcdefg") @@ -672,7 +672,7 @@ public async Task DirectMessagesEventsNew_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterMessageEventSingle())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.DirectMessagesEventsNew(recipientId: 12345L, text: "hogehoge", mediaId: 67890L) @@ -691,7 +691,7 @@ public async Task DirectMessagesEventsDestroy_Test() ) .Returns(Task.CompletedTask); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.DirectMessagesEventsDestroy(eventId: "100") @@ -717,7 +717,7 @@ public async Task UsersShow_Test() ) .ReturnsAsync(new TwitterUser { ScreenName = "twitterapi" }); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.UsersShow(screenName: "twitterapi") @@ -743,7 +743,7 @@ public async Task UsersLookup_Test() ) .ReturnsAsync(Array.Empty()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.UsersLookup(userIds: new[] { "11111", "22222" }) @@ -766,7 +766,7 @@ public async Task UsersReportSpam_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUser { ScreenName = "twitterapi" })); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.UsersReportSpam(screenName: "twitterapi") @@ -795,7 +795,7 @@ public async Task FavoritesList_Test() ) .ReturnsAsync(Array.Empty()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.FavoritesList(200, maxId: 900L, sinceId: 100L) @@ -818,7 +818,7 @@ public async Task FavoritesCreate_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L })); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.FavoritesCreate(statusId: 100L) @@ -842,7 +842,7 @@ public async Task FavoritesDestroy_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterStatus { Id = 100L })); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.FavoritesDestroy(statusId: 100L) @@ -864,7 +864,7 @@ public async Task FriendshipsShow_Test() ) .ReturnsAsync(new TwitterFriendship()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.FriendshipsShow(sourceScreenName: "twitter", targetScreenName: "twitterapi") @@ -884,7 +884,7 @@ public async Task FriendshipsCreate_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterFriendship())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.FriendshipsCreate(screenName: "twitterapi") @@ -905,7 +905,7 @@ public async Task FriendshipsDestroy_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterFriendship())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.FriendshipsDestroy(screenName: "twitterapi") @@ -927,7 +927,7 @@ public async Task NoRetweetIds_Test() ) .ReturnsAsync(Array.Empty()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.NoRetweetIds() @@ -948,7 +948,7 @@ public async Task FollowersIds_Test() ) .ReturnsAsync(new TwitterIds()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.FollowersIds(cursor: -1L) @@ -969,7 +969,7 @@ public async Task MutesUsersIds_Test() ) .ReturnsAsync(new TwitterIds()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.MutesUsersIds(cursor: -1L) @@ -990,7 +990,7 @@ public async Task BlocksIds_Test() ) .ReturnsAsync(new TwitterIds()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.BlocksIds(cursor: -1L) @@ -1013,7 +1013,7 @@ public async Task BlocksCreate_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUser())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.BlocksCreate(screenName: "twitterapi") @@ -1037,7 +1037,7 @@ public async Task BlocksDestroy_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUser())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.BlocksDestroy(screenName: "twitterapi") @@ -1067,7 +1067,7 @@ public async Task AccountVerifyCredentials_Test() ScreenName = "opentween", }); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.AccountVerifyCredentials() @@ -1098,7 +1098,7 @@ public async Task AccountUpdateProfile_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUser())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.AccountUpdateProfile(name: "Name", url: "http://example.com/", location: "Location", description: "") @@ -1126,7 +1126,7 @@ public async Task AccountUpdateProfileImage_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUser())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.AccountUpdateProfileImage(media) @@ -1148,7 +1148,7 @@ public async Task ApplicationRateLimitStatus_Test() ) .ReturnsAsync(new TwitterRateLimits()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.ApplicationRateLimitStatus() @@ -1169,7 +1169,7 @@ public async Task Configuration_Test() ) .ReturnsAsync(new TwitterConfiguration()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.Configuration() @@ -1194,7 +1194,7 @@ public async Task MediaUploadInit_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaInit())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.MediaUploadInit(totalBytes: 123456L, mediaType: "image/png", mediaCategory: "dm_image") @@ -1222,7 +1222,7 @@ public async Task MediaUploadAppend_Test() ) .Returns(Task.CompletedTask); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.MediaUploadAppend(mediaId: 11111L, segmentIndex: 1, media: media) @@ -1245,7 +1245,7 @@ public async Task MediaUploadFinalize_Test() ) .ReturnsAsync(LazyJson.Create(new TwitterUploadMediaResult())); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.MediaUploadFinalize(mediaId: 11111L) @@ -1270,7 +1270,7 @@ public async Task MediaUploadStatus_Test() ) .ReturnsAsync(new TwitterUploadMediaResult()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.MediaUploadStatus(mediaId: 11111L) @@ -1290,7 +1290,7 @@ public async Task MediaMetadataCreate_Test() ) .Returns(Task.CompletedTask); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge") @@ -1313,7 +1313,7 @@ public async Task UserStreams_Test() ) .ReturnsAsync(new MemoryStream()); - using var twitterApi = new TwitterApi(); + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); twitterApi.apiConnection = mock.Object; var observable = twitterApi.UserStreams(replies: "all", track: "OpenTween"); diff --git a/OpenTween.Tests/ApiKeyTest.cs b/OpenTween.Tests/ApiKeyTest.cs new file mode 100644 index 000000000..67aa9f6e6 --- /dev/null +++ b/OpenTween.Tests/ApiKeyTest.cs @@ -0,0 +1,115 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween +{ + public class ApiKeyTest + { + [Fact] + public void Encrypt_FormatTest() + { + var password = "hoge"; + var plainText = "aaaaaaa"; + var encrypted = ApiKey.Encrypt(password, plainText); + Assert.StartsWith("%e%", encrypted); + Assert.Equal(5, encrypted.Split('%').Length); + } + + [Fact] + public void Encrypt_NonceTest() + { + // 同じ平文に対する暗号文を繰り返し生成しても出力は毎回変化する + var password = "hoge"; + var plainText = "aaaaaaa"; + var encrypted1 = ApiKey.Encrypt(password, plainText); + var encrypted2 = ApiKey.Encrypt(password, plainText); + Assert.NotEqual(encrypted1, encrypted2); + } + + [Fact] + public void Decrypt_Test() + { + var password = "password"; + var encrypted = "%e%m6EH2dECH7HWT9SFE0SK4Q==%mAAWPhPALf48s32s/yQarg==%zoCs8crMqZN6Nfj8ALkl2R3kbD/FORecuepU1LJ3CK0="; + var decrypted = ApiKey.Decrypt(password, encrypted); + Assert.Equal("hogehoge", decrypted); + } + + [Fact] + public void Decrypt_PlainTextTest() + { + // %e% から始まっていない文字列は平文として何もせずに返す + var password = "password"; + var plainText = "plaintext"; + var decrypted = ApiKey.Decrypt(password, plainText); + Assert.Equal("plaintext", decrypted); + } + + [Fact] + public void Decrypt_InvalidFormatTest() + { + var password = "password"; + var encrypted = "%e%INVALID_FORMAT"; + Assert.Throws(() => ApiKey.Decrypt(password, encrypted)); + } + + [Fact] + public void Decrypt_InvalidBase64Test() + { + var password = "password"; + var encrypted = "%e%!!!!!!!!!!%!!!!!!!!!!%!!!!!!!!!!"; + Assert.Throws(() => ApiKey.Decrypt(password, encrypted)); + } + + [Fact] + public void Decrypt_InvalidHMACTest() + { + var password = "password"; + var encrypted = "%e%m6EH2dECH7HWT9SFE0SK4Q==%mAAWPhPALf48s32s/yQarg==%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + Assert.Throws(() => ApiKey.Decrypt(password, encrypted)); + } + + [Fact] + public void Decrypt_InvalidHMACLengthTest() + { + // HMAC が途中まで一致しているが長さが足りない場合 + var password = "password"; + var encrypted = "%e%m6EH2dECH7HWT9SFE0SK4Q==%mAAWPhPALf48s32s/yQarg==%zoCs8"; + Assert.Throws(() => ApiKey.Decrypt(password, encrypted)); + } + + [Fact] + public void EncryptAndDecrypt_Test() + { + var password = "hoge"; + var plainText = "aaaaaaa"; + var encrypted = ApiKey.Encrypt(password, plainText); + Assert.Equal(plainText, ApiKey.Decrypt(password, encrypted)); + } + } +} diff --git a/OpenTween.Tests/Connection/OAuthUtilityTest.cs b/OpenTween.Tests/Connection/OAuthUtilityTest.cs index 2328ae6cb..2079718f0 100644 --- a/OpenTween.Tests/Connection/OAuthUtilityTest.cs +++ b/OpenTween.Tests/Connection/OAuthUtilityTest.cs @@ -34,7 +34,7 @@ public class OAuthUtilityTest [Fact] public void GetOAuthParameter_Test() { - var param = OAuthUtility.GetOAuthParameter("ConsumerKey", "Token"); + var param = OAuthUtility.GetOAuthParameter(ApiKey.Create("ConsumerKey"), "Token"); Assert.Equal("ConsumerKey", param["oauth_consumer_key"]); Assert.Equal("HMAC-SHA1", param["oauth_signature_method"]); @@ -53,7 +53,7 @@ public void CreateSignature_Test() { // GET http://example.com/hoge?aaa=foo に対する署名を生成 // 実際の param は oauth_consumer_key などのパラメーターが加わった状態で渡される - var oauthSignature = OAuthUtility.CreateSignature("ConsumerSecret", "TokenSecret", + var oauthSignature = OAuthUtility.CreateSignature(ApiKey.Create("ConsumerSecret"), "TokenSecret", "GET", new Uri("http://example.com/hoge"), new Dictionary { ["aaa"] = "foo" }); var expectSignatureBase = "GET&http%3A%2F%2Fexample.com%2Fhoge&aaa%3Dfoo"; @@ -69,7 +69,7 @@ public void CreateSignature_NormarizeParametersTest() { // GET http://example.com/hoge?aaa=foo&bbb=bar に対する署名を生成 // 複数のパラメータが渡される場合は name 順でソートされる - var oauthSignature = OAuthUtility.CreateSignature("ConsumerSecret", "TokenSecret", + var oauthSignature = OAuthUtility.CreateSignature(ApiKey.Create("ConsumerSecret"), "TokenSecret", "GET", new Uri("http://example.com/hoge"), new Dictionary { ["bbb"] = "bar", ["aaa"] = "foo", @@ -88,7 +88,7 @@ public void CreateSignature_EmptyTokenSecretTest() { // GET http://example.com/hoge?aaa=foo に対する署名を生成 // リクエストトークンの発行時は tokenSecret が空の状態で署名を生成することになる - var oauthSignature = OAuthUtility.CreateSignature("ConsumerSecret", null, + var oauthSignature = OAuthUtility.CreateSignature(ApiKey.Create("ConsumerSecret"), null, "GET", new Uri("http://example.com/hoge"), new Dictionary { ["aaa"] = "foo" }); var expectSignatureBase = "GET&http%3A%2F%2Fexample.com%2Fhoge&aaa%3Dfoo"; @@ -104,7 +104,7 @@ public void CreateAuthorization_Test() { var authorization = OAuthUtility.CreateAuthorization( "GET", new Uri("http://example.com/hoge"), new Dictionary { ["aaa"] = "hoge" }, - "ConsumerKey", "ConsumerSecret", "AccessToken", "AccessSecret", "Realm"); + ApiKey.Create("ConsumerKey"), ApiKey.Create("ConsumerSecret"), "AccessToken", "AccessSecret", "Realm"); Assert.StartsWith("OAuth ", authorization, StringComparison.Ordinal); diff --git a/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs b/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs index a86270a91..612e73e8e 100644 --- a/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs +++ b/OpenTween.Tests/Connection/TwitterApiConnectionTest.cs @@ -56,7 +56,7 @@ public async Task GetAsync_Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(x => @@ -95,7 +95,7 @@ public async Task GetAsync_AbsoluteUriTest() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(x => @@ -133,7 +133,7 @@ public async Task GetAsync_UpdateRateLimitTest() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(x => @@ -174,7 +174,7 @@ public async Task GetAsync_ErrorStatusTest() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(x => @@ -202,7 +202,7 @@ public async Task GetAsync_ErrorJsonTest() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(x => @@ -232,7 +232,7 @@ public async Task GetStreamAsync_Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); using var image = TestUtils.CreateDummyImage(); apiConnection.http = http; @@ -279,7 +279,7 @@ public async Task PostLazyAsync_Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(async x => @@ -322,7 +322,7 @@ public async Task PostLazyAsync_MultipartTest() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.httpUpload = http; using var image = TestUtils.CreateDummyImage(); @@ -394,7 +394,7 @@ public async Task PostLazyAsync_Multipart_NullTest() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.httpUpload = http; mockHandler.Enqueue(async x => @@ -441,7 +441,7 @@ public async Task PostJsonAsync_Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(async x => @@ -473,7 +473,7 @@ public async Task PostJsonAsync_T_Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(async x => @@ -513,7 +513,7 @@ public async Task DeleteAsync_Test() { using var mockHandler = new HttpMessageHandlerMock(); using var http = new HttpClient(mockHandler); - using var apiConnection = new TwitterApiConnection("", ""); + using var apiConnection = new TwitterApiConnection(ApiKey.Create(""), ApiKey.Create(""), "", ""); apiConnection.http = http; mockHandler.Enqueue(x => diff --git a/OpenTween.Tests/MediaSelectorTest.cs b/OpenTween.Tests/MediaSelectorTest.cs index 8590e68bb..de4d3ca1d 100644 --- a/OpenTween.Tests/MediaSelectorTest.cs +++ b/OpenTween.Tests/MediaSelectorTest.cs @@ -9,6 +9,7 @@ using System.Text; using System.Text.RegularExpressions; using Moq; +using OpenTween.Api; using OpenTween.Api.DataModel; using Xunit; @@ -30,7 +31,8 @@ private void MyCommonSetup() [Fact] public void Initialize_TwitterTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector(); twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -51,7 +53,8 @@ public void Initialize_TwitterTest() [Fact] public void Initialize_ImgurTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector(); twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Imgur"); @@ -70,7 +73,8 @@ public void Initialize_ImgurTest() [Fact] public void BeginSelection_BlankTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -97,7 +101,8 @@ public void BeginSelection_BlankTest() [Fact] public void BeginSelection_FilePathTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -129,7 +134,8 @@ public void BeginSelection_FilePathTest() [Fact] public void BeginSelection_MemoryImageTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -164,7 +170,8 @@ public void BeginSelection_MemoryImageTest() [Fact] public void BeginSelection_MultiImageTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -188,7 +195,8 @@ public void BeginSelection_MultiImageTest() [Fact] public void EndSelection_Test() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -211,7 +219,8 @@ public void EndSelection_Test() [Fact] public void PageChange_Test() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -254,7 +263,8 @@ public void PageChange_Test() [Fact] public void PageChange_AlternativeTextTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -291,7 +301,8 @@ public void PageChange_AlternativeTextTest() [Fact] public void PageChange_ImageDisposeTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -319,7 +330,8 @@ public void PageChange_ImageDisposeTest() [Fact] public void ImagePathInput_Test() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -344,7 +356,8 @@ public void ImagePathInput_Test() [Fact] public void ImagePathInput_ReplaceFileMediaItemTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -372,7 +385,8 @@ public void ImagePathInput_ReplaceFileMediaItemTest() [Fact] public void ImagePathInput_ReplaceMemoryImageMediaItemTest() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); @@ -411,7 +425,8 @@ public void ImagePathInput_ReplaceMemoryImageMediaItemTest() [Fact] public void ImageServiceChange_Test() { - using var twitter = new Twitter(); + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); using var mediaSelector = new MediaSelector { Visible = false, Enabled = false }; twitter.Initialize("", "", "", 0L); mediaSelector.Initialize(twitter, TwitterConfiguration.DefaultConfiguration(), "Twitter"); diff --git a/OpenTween.Tests/Thumbnail/Services/FoursquareCheckinTest.cs b/OpenTween.Tests/Thumbnail/Services/FoursquareCheckinTest.cs index 8c506d09c..0f41b7759 100644 --- a/OpenTween.Tests/Thumbnail/Services/FoursquareCheckinTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/FoursquareCheckinTest.cs @@ -71,7 +71,7 @@ public async Task GetThumbnailInfoAsync_NewUrlTest() var handler = new HttpMessageHandlerMock(); using (var http = new HttpClient(handler)) { - var service = new FoursquareCheckin(http); + var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); handler.Enqueue(x => { @@ -81,8 +81,8 @@ public async Task GetThumbnailInfoAsync_NewUrlTest() var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - Assert.Equal(ApplicationSettings.FoursquareClientId, query["client_id"]); - Assert.Equal(ApplicationSettings.FoursquareClientSecret, query["client_secret"]); + Assert.Equal("fake_client_id", query["client_id"]); + Assert.Equal("fake_client_secret", query["client_secret"]); Assert.NotNull(query["v"]); Assert.Equal("xxxxxxxx", query["shortId"]); @@ -109,7 +109,7 @@ public async Task GetThumbnailInfoAsync_LegacyUrlTest() var handler = new HttpMessageHandlerMock(); using (var http = new HttpClient(handler)) { - var service = new FoursquareCheckin(http); + var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); handler.Enqueue(x => { @@ -119,8 +119,8 @@ public async Task GetThumbnailInfoAsync_LegacyUrlTest() var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - Assert.Equal(ApplicationSettings.FoursquareClientId, query["client_id"]); - Assert.Equal(ApplicationSettings.FoursquareClientSecret, query["client_secret"]); + Assert.Equal("fake_client_id", query["client_id"]); + Assert.Equal("fake_client_secret", query["client_secret"]); Assert.NotNull(query["v"]); Assert.Null(query["signature"]); @@ -147,7 +147,7 @@ public async Task GetThumbnailInfoAsync_LegacyUrlWithSignatureTest() var handler = new HttpMessageHandlerMock(); using (var http = new HttpClient(handler)) { - var service = new FoursquareCheckin(http); + var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); handler.Enqueue(x => { @@ -157,8 +157,8 @@ public async Task GetThumbnailInfoAsync_LegacyUrlWithSignatureTest() var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - Assert.Equal(ApplicationSettings.FoursquareClientId, query["client_id"]); - Assert.Equal(ApplicationSettings.FoursquareClientSecret, query["client_secret"]); + Assert.Equal("fake_client_id", query["client_id"]); + Assert.Equal("fake_client_secret", query["client_secret"]); Assert.NotNull(query["v"]); Assert.Equal("aaaaaaa", query["signature"]); @@ -185,7 +185,7 @@ public async Task GetThumbnailInfoAsync_GeoLocatedTweetTest() var handler = new HttpMessageHandlerMock(); using (var http = new HttpClient(handler)) { - var service = new FoursquareCheckin(http); + var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); handler.Enqueue(x => { @@ -208,6 +208,20 @@ await service.GetThumbnailInfoAsync( } } + [Fact] + public async Task GetThumbnailInfoAsync_ApiKeyErrorTest() + { + var handler = new HttpMessageHandlerMock(); + using var http = new HttpClient(handler); + var service = new FoursquareCheckin(http, ApiKey.Create("%e%INVALID_API_KEY"), ApiKey.Create("%e%INVALID_API_KEY")); + + var post = new PostClass(); + var thumb = await service.GetThumbnailInfoAsync("https://www.swarmapp.com/c/xxxxxxxx", post, CancellationToken.None) + .ConfigureAwait(false); + + Assert.Null(thumb); + } + [Fact] public void ParseInLocation_Test() { diff --git a/OpenTween.Tests/Thumbnail/Services/TinamiTest.cs b/OpenTween.Tests/Thumbnail/Services/TinamiTest.cs index 5e2e6c91a..a7b51e0ba 100644 --- a/OpenTween.Tests/Thumbnail/Services/TinamiTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/TinamiTest.cs @@ -43,11 +43,11 @@ class TestTinami : Tinami public string FakeXml { get; set; } = ""; public TestTinami() - : base(null) + : base(ApiKey.Create("fake_api_key"), null) { } - protected override Task FetchContentInfoApiAsync(string contentId, CancellationToken token) + protected override Task FetchContentInfoApiAsync(string apiKey, string contentId, CancellationToken token) => Task.FromResult(XDocument.Parse(this.FakeXml)); } @@ -92,5 +92,16 @@ public async Task ApiErrorTest() Assert.Null(thumbinfo); } + + [Fact] + public async Task GetThumbnailInfoAsync_ApiKeyErrorTest() + { + var service = new Tinami(ApiKey.Create("%e%INVALID_API_KEY"), null); + + var thumbinfo = await service.GetThumbnailInfoAsync("http://www.tinami.com/view/12345", new PostClass(), CancellationToken.None) + .ConfigureAwait(false); + + Assert.Null(thumbinfo); + } } } diff --git a/OpenTween.Tests/Thumbnail/Services/TumblrTest.cs b/OpenTween.Tests/Thumbnail/Services/TumblrTest.cs index fd56ed657..e31155dce 100644 --- a/OpenTween.Tests/Thumbnail/Services/TumblrTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/TumblrTest.cs @@ -70,7 +70,7 @@ public async Task GetThumbnailInfoAsync_RequestTest() var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - Assert.Equal(ApplicationSettings.TumblrConsumerKey, query["api_key"]); + Assert.Equal("fake_api_key", query["api_key"]); Assert.Equal("1234567", query["id"]); return new HttpResponseMessage(HttpStatusCode.OK) @@ -84,7 +84,7 @@ public async Task GetThumbnailInfoAsync_RequestTest() using (var http = new HttpClient(handler)) { - var service = new Tumblr(http); + var service = new Tumblr(ApiKey.Create("fake_api_key"), http); var url = "http://hoge.tumblr.com/post/1234567/tetetete"; await service.GetThumbnailInfoAsync(url, new PostClass(), CancellationToken.None) @@ -107,7 +107,7 @@ public async Task GetThumbnailInfoAsync_CustomHostnameRequestTest() var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - Assert.Equal(ApplicationSettings.TumblrConsumerKey, query["api_key"]); + Assert.Equal("fake_api_key", query["api_key"]); Assert.Equal("1234567", query["id"]); return new HttpResponseMessage(HttpStatusCode.OK) @@ -121,7 +121,7 @@ public async Task GetThumbnailInfoAsync_CustomHostnameRequestTest() using (var http = new HttpClient(handler)) { - var service = new Tumblr(http); + var service = new Tumblr(ApiKey.Create("fake_api_key"), http); // Tumblrのカスタムドメイン名を使ってるっぽいURL var url = "http://tumblr.example.com/post/1234567/tetetete"; @@ -131,5 +131,19 @@ public async Task GetThumbnailInfoAsync_CustomHostnameRequestTest() Assert.Equal(0, handler.QueueCount); } + + [Fact] + public async Task GetThumbnailInfoAsync_ApiKeyErrorTest() + { + var handler = new HttpMessageHandlerMock(); + + using var http = new HttpClient(handler); + var service = new Tumblr(ApiKey.Create("%e%INVALID_API_KEY"), http); + + var url = "http://hoge.tumblr.com/post/1234567/tetetete"; + var thumb = await service.GetThumbnailInfoAsync(url, new PostClass(), CancellationToken.None) + .ConfigureAwait(false); + Assert.Null(thumb); + } } } diff --git a/OpenTween.Tests/TwitterTest.cs b/OpenTween.Tests/TwitterTest.cs index 56b2bf8ef..df02eb7a1 100644 --- a/OpenTween.Tests/TwitterTest.cs +++ b/OpenTween.Tests/TwitterTest.cs @@ -24,6 +24,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; +using OpenTween.Api; using OpenTween.Api.DataModel; using OpenTween.Models; using OpenTween.Setting; @@ -541,108 +542,108 @@ public void GetApiResultCount_AdditionalCountTest() [Fact] public void GetTextLengthRemain_Test() { - using (var twitter = new Twitter()) - { - Assert.Equal(280, twitter.GetTextLengthRemain("")); - Assert.Equal(272, twitter.GetTextLengthRemain("hogehoge")); - } + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); + + Assert.Equal(280, twitter.GetTextLengthRemain("")); + Assert.Equal(272, twitter.GetTextLengthRemain("hogehoge")); } [Fact] public void GetTextLengthRemain_DirectMessageTest() { - using (var twitter = new Twitter()) - { - // 2015年8月から DM の文字数上限が 10,000 文字に変更された - // https://twittercommunity.com/t/41348 - twitter.Configuration.DmTextCharacterLimit = 10000; + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); - Assert.Equal(10000, twitter.GetTextLengthRemain("D twitter ")); - Assert.Equal(9992, twitter.GetTextLengthRemain("D twitter hogehoge")); + // 2015年8月から DM の文字数上限が 10,000 文字に変更された + // https://twittercommunity.com/t/41348 + twitter.Configuration.DmTextCharacterLimit = 10000; - // t.co に短縮される分の文字数を考慮 - twitter.Configuration.ShortUrlLength = 20; - Assert.Equal(9971, twitter.GetTextLengthRemain("D twitter hogehoge http://example.com/")); + Assert.Equal(10000, twitter.GetTextLengthRemain("D twitter ")); + Assert.Equal(9992, twitter.GetTextLengthRemain("D twitter hogehoge")); - twitter.Configuration.ShortUrlLengthHttps = 21; - Assert.Equal(9970, twitter.GetTextLengthRemain("D twitter hogehoge https://example.com/")); - } + // t.co に短縮される分の文字数を考慮 + twitter.Configuration.ShortUrlLength = 20; + Assert.Equal(9971, twitter.GetTextLengthRemain("D twitter hogehoge http://example.com/")); + + twitter.Configuration.ShortUrlLengthHttps = 21; + Assert.Equal(9970, twitter.GetTextLengthRemain("D twitter hogehoge https://example.com/")); } [Fact] public void GetTextLengthRemain_UrlTest() { - using (var twitter = new Twitter()) - { - // t.co に短縮される分の文字数を考慮 - twitter.TextConfiguration.TransformedURLLength = 20; - Assert.Equal(260, twitter.GetTextLengthRemain("http://example.com/")); - Assert.Equal(260, twitter.GetTextLengthRemain("http://example.com/hogehoge")); - Assert.Equal(251, twitter.GetTextLengthRemain("hogehoge http://example.com/")); - - Assert.Equal(260, twitter.GetTextLengthRemain("https://example.com/")); - Assert.Equal(260, twitter.GetTextLengthRemain("https://example.com/hogehoge")); - Assert.Equal(251, twitter.GetTextLengthRemain("hogehoge https://example.com/")); - } + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); + + // t.co に短縮される分の文字数を考慮 + twitter.TextConfiguration.TransformedURLLength = 20; + Assert.Equal(260, twitter.GetTextLengthRemain("http://example.com/")); + Assert.Equal(260, twitter.GetTextLengthRemain("http://example.com/hogehoge")); + Assert.Equal(251, twitter.GetTextLengthRemain("hogehoge http://example.com/")); + + Assert.Equal(260, twitter.GetTextLengthRemain("https://example.com/")); + Assert.Equal(260, twitter.GetTextLengthRemain("https://example.com/hogehoge")); + Assert.Equal(251, twitter.GetTextLengthRemain("hogehoge https://example.com/")); } [Fact] public void GetTextLengthRemain_UrlWithoutSchemeTest() { - using (var twitter = new Twitter()) - { - // t.co に短縮される分の文字数を考慮 - twitter.TextConfiguration.TransformedURLLength = 20; - Assert.Equal(260, twitter.GetTextLengthRemain("example.com")); - Assert.Equal(260, twitter.GetTextLengthRemain("example.com/hogehoge")); - Assert.Equal(251, twitter.GetTextLengthRemain("hogehoge example.com")); - - // スキーム (http://) を省略かつ末尾が ccTLD の場合は t.co に短縮されない - Assert.Equal(270, twitter.GetTextLengthRemain("example.jp")); - // ただし、末尾にパスが続く場合は t.co に短縮される - Assert.Equal(260, twitter.GetTextLengthRemain("example.jp/hogehoge")); - } + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); + + // t.co に短縮される分の文字数を考慮 + twitter.TextConfiguration.TransformedURLLength = 20; + Assert.Equal(260, twitter.GetTextLengthRemain("example.com")); + Assert.Equal(260, twitter.GetTextLengthRemain("example.com/hogehoge")); + Assert.Equal(251, twitter.GetTextLengthRemain("hogehoge example.com")); + + // スキーム (http://) を省略かつ末尾が ccTLD の場合は t.co に短縮されない + Assert.Equal(270, twitter.GetTextLengthRemain("example.jp")); + // ただし、末尾にパスが続く場合は t.co に短縮される + Assert.Equal(260, twitter.GetTextLengthRemain("example.jp/hogehoge")); } [Fact] public void GetTextLengthRemain_SurrogatePairTest() { - using (var twitter = new Twitter()) - { - Assert.Equal(278, twitter.GetTextLengthRemain("🍣")); - Assert.Equal(267, twitter.GetTextLengthRemain("🔥🐔🔥 焼き鳥")); - } + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); + + Assert.Equal(278, twitter.GetTextLengthRemain("🍣")); + Assert.Equal(267, twitter.GetTextLengthRemain("🔥🐔🔥 焼き鳥")); } [Fact] public void GetTextLengthRemain_EmojiTest() { - using (var twitter = new Twitter()) - { - // 絵文字の文字数カウントの仕様変更に対するテストケース - // https://twittercommunity.com/t/114607 - - Assert.Equal(279, twitter.GetTextLengthRemain("©")); // 基本多言語面の絵文字 - Assert.Equal(277, twitter.GetTextLengthRemain("©\uFE0E")); // 異字体セレクタ付き (text style) - Assert.Equal(279, twitter.GetTextLengthRemain("©\uFE0F")); // 異字体セレクタ付き (emoji style) - Assert.Equal(278, twitter.GetTextLengthRemain("🍣")); // 拡張面の絵文字 - Assert.Equal(279, twitter.GetTextLengthRemain("#⃣")); // 合字で表現される絵文字 - Assert.Equal(278, twitter.GetTextLengthRemain("👦\U0001F3FF")); // Emoji modifier 付きの絵文字 - Assert.Equal(278, twitter.GetTextLengthRemain("\U0001F3FF")); // Emoji modifier 単体 - Assert.Equal(278, twitter.GetTextLengthRemain("👨\u200D🎨")); // ZWJ で結合された絵文字 - Assert.Equal(278, twitter.GetTextLengthRemain("🏃\u200D♀\uFE0F")); // ZWJ と異字体セレクタを含む絵文字 - } + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); + + // 絵文字の文字数カウントの仕様変更に対するテストケース + // https://twittercommunity.com/t/114607 + + Assert.Equal(279, twitter.GetTextLengthRemain("©")); // 基本多言語面の絵文字 + Assert.Equal(277, twitter.GetTextLengthRemain("©\uFE0E")); // 異字体セレクタ付き (text style) + Assert.Equal(279, twitter.GetTextLengthRemain("©\uFE0F")); // 異字体セレクタ付き (emoji style) + Assert.Equal(278, twitter.GetTextLengthRemain("🍣")); // 拡張面の絵文字 + Assert.Equal(279, twitter.GetTextLengthRemain("#⃣")); // 合字で表現される絵文字 + Assert.Equal(278, twitter.GetTextLengthRemain("👦\U0001F3FF")); // Emoji modifier 付きの絵文字 + Assert.Equal(278, twitter.GetTextLengthRemain("\U0001F3FF")); // Emoji modifier 単体 + Assert.Equal(278, twitter.GetTextLengthRemain("👨\u200D🎨")); // ZWJ で結合された絵文字 + Assert.Equal(278, twitter.GetTextLengthRemain("🏃\u200D♀\uFE0F")); // ZWJ と異字体セレクタを含む絵文字 } [Fact] public void GetTextLengthRemain_BrokenSurrogateTest() { - using (var twitter = new Twitter()) - { - // 投稿欄に IME から絵文字を入力すると HighSurrogate のみ入力された状態で TextChanged イベントが呼ばれることがある - Assert.Equal(278, twitter.GetTextLengthRemain("\ud83d")); - Assert.Equal(9999, twitter.GetTextLengthRemain("D twitter \ud83d")); - } + using var twitterApi = new TwitterApi(ApiKey.Create(""), ApiKey.Create("")); + using var twitter = new Twitter(twitterApi); + + // 投稿欄に IME から絵文字を入力すると HighSurrogate のみ入力された状態で TextChanged イベントが呼ばれることがある + Assert.Equal(278, twitter.GetTextLengthRemain("\ud83d")); + Assert.Equal(9999, twitter.GetTextLengthRemain("D twitter \ud83d")); } } } diff --git a/OpenTween/Api/BitlyApi.cs b/OpenTween/Api/BitlyApi.cs index 133d49461..8ec9dc037 100644 --- a/OpenTween/Api/BitlyApi.cs +++ b/OpenTween/Api/BitlyApi.cs @@ -45,16 +45,23 @@ public class BitlyApi public string EndUserLoginName { get; set; } = ""; public string EndUserApiKey { get; set; } = ""; + private readonly ApiKey clientId; + private readonly ApiKey clientSecret; + private HttpClient http => this.localHttpClient ?? Networking.Http; private readonly HttpClient? localHttpClient; public BitlyApi() - : this(null) + : this(ApplicationSettings.BitlyClientId, ApplicationSettings.BitlyClientSecret, null) { } - public BitlyApi(HttpClient? http) - => this.localHttpClient = http; + public BitlyApi(ApiKey clientId, ApiKey clientSecret, HttpClient? http) + { + this.clientId = clientId; + this.clientSecret = clientSecret; + this.localHttpClient = http; + } public async Task ShortenAsync(Uri srcUri, string? domain = null) { @@ -104,7 +111,12 @@ public async Task GetAccessTokenAsync(string username, string password) using var request = new HttpRequestMessage(HttpMethod.Post, endpoint); using var postContent = new FormUrlEncodedContent(param); - var authzParam = ApplicationSettings.BitlyClientId + ":" + ApplicationSettings.BitlyClientSecret; + if (!(this.clientId, this.clientSecret).TryGetValue(out var keyPair)) + throw new WebApiException("bit.ly APIキーが使用できません"); + + var (clientId, clientSecret) = keyPair; + + var authzParam = clientId + ":" + clientSecret; request.Headers.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes(authzParam))); request.Content = postContent; diff --git a/OpenTween/Api/ImgurApi.cs b/OpenTween/Api/ImgurApi.cs index ee7eeb372..0b9003ed3 100644 --- a/OpenTween/Api/ImgurApi.cs +++ b/OpenTween/Api/ImgurApi.cs @@ -37,17 +37,17 @@ namespace OpenTween.Api { public class ImgurApi : IImgurApi { - private readonly string clientId; + private readonly ApiKey clientId; private readonly HttpClient http; public static readonly Uri UploadEndpoint = new Uri("https://api.imgur.com/3/image.xml"); public ImgurApi() - : this(ApplicationSettings.ImgurClientID, null) + : this(ApplicationSettings.ImgurClientId, null) { } - public ImgurApi(string clientId, HttpClient? http) + public ImgurApi(ApiKey clientId, HttpClient? http) { this.clientId = clientId; @@ -97,6 +97,9 @@ public async Task UploadFileAsync(IMediaItem item, string title) private async Task SendRequestAsync(IMediaItem item, string title) { + if (!this.clientId.TryGetValue(out var clientId)) + throw new WebApiException("Err:imgur APIキーが使用できません"); + using var content = new MultipartFormDataContent(); using var mediaStream = item.OpenRead(); using var mediaContent = new StreamContent(mediaStream); @@ -106,7 +109,7 @@ private async Task SendRequestAsync(IMediaItem item, string content.Add(titleContent, "title"); using var request = new HttpRequestMessage(HttpMethod.Post, UploadEndpoint); - request.Headers.Authorization = new AuthenticationHeaderValue("Client-ID", this.clientId); + request.Headers.Authorization = new AuthenticationHeaderValue("Client-ID", clientId); request.Content = content; return await this.http.SendAsync(request) diff --git a/OpenTween/Api/MicrosoftTranslatorApi.cs b/OpenTween/Api/MicrosoftTranslatorApi.cs index b55835eed..7f5e16060 100644 --- a/OpenTween/Api/MicrosoftTranslatorApi.cs +++ b/OpenTween/Api/MicrosoftTranslatorApi.cs @@ -44,19 +44,27 @@ public class MicrosoftTranslatorApi public string AccessToken { get; internal set; } = ""; public DateTimeUtc RefreshAccessTokenAt { get; internal set; } = DateTimeUtc.MinValue; + private readonly ApiKey subscriptionKey; + private HttpClient Http => this.localHttpClient ?? Networking.Http; private readonly HttpClient? localHttpClient; public MicrosoftTranslatorApi() - : this(null) + : this(ApplicationSettings.TranslatorSubscriptionKey, null) { } - public MicrosoftTranslatorApi(HttpClient? http) - => this.localHttpClient = http; + public MicrosoftTranslatorApi(ApiKey subscriptionKey, HttpClient? http) + { + this.subscriptionKey = subscriptionKey; + this.localHttpClient = http; + } public async Task TranslateAsync(string text, string langTo, string? langFrom = null) { + if (!this.subscriptionKey.TryGetValue(out _)) + throw new WebApiException("APIキーが使用できません"); + await this.UpdateAccessTokenIfExpired() .ConfigureAwait(false); @@ -83,7 +91,8 @@ await this.UpdateAccessTokenIfExpired() using var response = await this.Http.SendAsync(request) .ConfigureAwait(false); - response.EnsureSuccessStatusCode(); + if (!response.IsSuccessStatusCode) + throw new WebApiException(response.StatusCode.ToString()); var responseJson = await response.Content.ReadAsByteArrayAsync() .ConfigureAwait(false); @@ -112,7 +121,7 @@ public async Task UpdateAccessTokenIfExpired() internal virtual async Task<(string AccessToken, TimeSpan ExpiresIn)> GetAccessTokenAsync() { using var request = new HttpRequestMessage(HttpMethod.Post, IssueTokenEndpoint); - request.Headers.Add("Ocp-Apim-Subscription-Key", ApplicationSettings.TranslatorSubscriptionKey); + request.Headers.Add("Ocp-Apim-Subscription-Key", this.subscriptionKey.Value); using var response = await this.Http.SendAsync(request) .ConfigureAwait(false); diff --git a/OpenTween/Api/MobypictureApi.cs b/OpenTween/Api/MobypictureApi.cs index 423e65fa2..255267e6e 100644 --- a/OpenTween/Api/MobypictureApi.cs +++ b/OpenTween/Api/MobypictureApi.cs @@ -36,7 +36,7 @@ namespace OpenTween.Api { public class MobypictureApi : IMobypictureApi { - private readonly string apiKey; + private readonly ApiKey apiKey; private readonly HttpClient http; public static readonly Uri UploadEndpoint = new Uri("https://api.mobypicture.com/2.0/upload.xml"); @@ -49,7 +49,7 @@ public MobypictureApi(TwitterApi twitterApi) { } - public MobypictureApi(string apiKey, TwitterApi twitterApi) + public MobypictureApi(ApiKey apiKey, TwitterApi twitterApi) { this.apiKey = apiKey; @@ -58,7 +58,7 @@ public MobypictureApi(string apiKey, TwitterApi twitterApi) this.http.Timeout = Networking.UploadImageTimeout; } - public MobypictureApi(string apiKey, HttpClient http) + public MobypictureApi(ApiKey apiKey, HttpClient http) { this.apiKey = apiKey; this.http = http; @@ -98,13 +98,16 @@ public async Task UploadFileAsync(IMediaItem item, string message) private async Task SendRequestAsync(IMediaItem item, string message) { + if (!this.apiKey.TryGetValue(out var apiKey)) + throw new WebApiException("Err:Mobypicture APIキーが使用できません"); + // 参照: http://developers.mobypicture.com/documentation/2-0/upload/ using var request = new HttpRequestMessage(HttpMethod.Post, UploadEndpoint); using var multipart = new MultipartFormDataContent(); request.Content = multipart; - using var apiKeyContent = new StringContent(this.apiKey); + using var apiKeyContent = new StringContent(apiKey); using var messageContent = new StringContent(message); using var mediaStream = item.OpenRead(); using var mediaContent = new StreamContent(mediaStream); diff --git a/OpenTween/Api/TwitterApi.cs b/OpenTween/Api/TwitterApi.cs index f651b8a28..593c3d65b 100644 --- a/OpenTween/Api/TwitterApi.cs +++ b/OpenTween/Api/TwitterApi.cs @@ -42,9 +42,18 @@ public sealed class TwitterApi : IDisposable internal IApiConnection? apiConnection; + private readonly ApiKey consumerKey; + private readonly ApiKey consumerSecret; + + public TwitterApi(ApiKey consumerKey, ApiKey consumerSecret) + { + this.consumerKey = consumerKey; + this.consumerSecret = consumerSecret; + } + public void Initialize(string accessToken, string accessSecret, long userId, string screenName) { - var newInstance = new TwitterApiConnection(accessToken, accessSecret); + var newInstance = new TwitterApiConnection(this.consumerKey, this.consumerSecret, accessToken, accessSecret); var oldInstance = Interlocked.Exchange(ref this.apiConnection, newInstance); oldInstance?.Dispose(); diff --git a/OpenTween/ApiKey.cs b/OpenTween/ApiKey.cs new file mode 100644 index 000000000..fb8246f39 --- /dev/null +++ b/OpenTween/ApiKey.cs @@ -0,0 +1,240 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; + +namespace OpenTween +{ + public class ApiKey + { + private static readonly string EncryptionPrefix = "%e%"; + private static readonly int SaltSize = 16; + private static readonly int KeySize = 32; + private static readonly int BlockSize = 16; + private static readonly int IterationCount = 10_000; + private static readonly HashAlgorithmName HashAlgorithm = HashAlgorithmName.SHA256; + + private readonly string rawKey; + private readonly Lazy decryptLazy; + + /// + /// 平文の API キー + /// + /// + public string Value => this.decryptLazy.Value; + + private ApiKey(string password, string rawKey) + { + this.rawKey = rawKey; + this.decryptLazy = new Lazy( + () => Decrypt(password, this.rawKey) + ); + } + + /// + /// 平文の API キーを返します + /// + /// + /// 成功した場合は true、暗号化された API キーの復号に失敗した場合は false を返します + /// + public bool TryGetValue([NotNullWhen(true)]out string output) + { + try + { + output = this.Value; + return true; + } + catch (ApiKeyDecryptException) + { + output = null!; + return false; + } + } + + /// + /// インスタンスを作成します + /// + public static ApiKey Create(string rawKey) + => Create(ApplicationSettings.EncryptionPassword, rawKey); + + /// + /// インスタンスを作成します + /// + public static ApiKey Create(string password, string rawKey) + => new ApiKey(password, rawKey); + + /// + /// 指定された文字列を暗号化して返します + /// + public static string Encrypt(string password, string plainText) + { + var salt = GenerateSalt(); + var (encryptionKey, iv, macKey) = GenerateKeyAndIV(password, salt); + + using var aes = CreateAes(); + aes.Key = encryptionKey; + aes.IV = iv; + + var plainBytes = Encoding.UTF8.GetBytes(plainText); + using var encryptor = aes.CreateEncryptor(); + using var memoryStream = new MemoryStream(plainBytes); + using var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Read); + + using var cipherStream = new MemoryStream(capacity: plainBytes.Length + BlockSize + SaltSize); + cryptoStream.CopyTo(cipherStream); + + var cipherBytes = cipherStream.ToArray(); + var macBytes = GenerateMAC(plainBytes, macKey); + var saltText = Convert.ToBase64String(salt); + var cipherText = Convert.ToBase64String(cipherBytes); + var macText = Convert.ToBase64String(macBytes); + + return $"{EncryptionPrefix}{saltText}%{cipherText}%{macText}"; + } + + /// + /// 暗号化された文字列を復号します + /// + /// + public static string Decrypt(string password, string encryptedText) + { + // 先頭が "%e%" から始まっていない場合、APIキーは平文のまま書かれているものとして扱う + if (!encryptedText.StartsWith(EncryptionPrefix)) + return encryptedText; + + var splitted = encryptedText.Split('%'); + if (splitted.Length != 5) + throw new ApiKeyDecryptException("暗号文のフォーマットが不正です"); + + byte[] salt, cipherBytes, macBytes; + try + { + // e.g. "%e%...salt...%...cipher...%...mac..." + salt = Convert.FromBase64String(splitted[2]); + cipherBytes = Convert.FromBase64String(splitted[3]); + macBytes = Convert.FromBase64String(splitted[4]); + } + catch (FormatException ex) + { + throw new ApiKeyDecryptException("不正な Base64 フォーマットです", ex); + } + + var (encryptionKey, iv, macKey) = GenerateKeyAndIV(password, salt); + using var aes = CreateAes(); + aes.Key = encryptionKey; + aes.IV = iv; + + byte[] decryptedBytes; + try + { + using var decryptor = aes.CreateDecryptor(); + using var memoryStream = new MemoryStream(cipherBytes); + using var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read); + + using var decryptedStream = new MemoryStream(capacity: cipherBytes.Length); + cryptoStream.CopyTo(decryptedStream); + + decryptedBytes = decryptedStream.ToArray(); + } + catch (CryptographicException ex) + { + throw new ApiKeyDecryptException("API キーの復号に失敗しました", ex); + } + + var macBytesExpected = GenerateMAC(decryptedBytes, macKey); + + var isValid = macBytes.Length == macBytesExpected.Length && + Enumerable.Zip(macBytes, macBytesExpected, (x, y) => x == y).All(x => x); + if (!isValid) + throw new ApiKeyDecryptException("ダイジェストが一致しません"); + + return Encoding.UTF8.GetString(decryptedBytes); + } + + private static byte[] GenerateSalt() + { + using var random = new RNGCryptoServiceProvider(); + var salt = new byte[SaltSize]; + random.GetBytes(salt); + return salt; + } + + private static (byte[], byte[], byte[]) GenerateKeyAndIV(string password, byte[] salt) + { + using var generator = new Rfc2898DeriveBytes(password, salt, IterationCount, HashAlgorithm); + var encryptionKey = generator.GetBytes(KeySize); + var iv = generator.GetBytes(BlockSize); + var macKey = generator.GetBytes(KeySize); + return (encryptionKey, iv, macKey); + } + + private static byte[] GenerateMAC(byte[] source, byte[] key) + { + using var hmac = new HMACSHA256(key); + return hmac.ComputeHash(source); + } + + private static Aes CreateAes() + { + var aes = Aes.Create(); + aes.KeySize = KeySize * 8; + aes.BlockSize = BlockSize * 8; + aes.Mode = CipherMode.CBC; + aes.Padding = PaddingMode.PKCS7; + return aes; + } + } + + public static class ApiKeyExtensions + { + public static bool TryGetValue(this ValueTuple apiKeys, out ValueTuple decryptedKeys) + { + var (apiKey1, apiKey2) = apiKeys; + if (apiKey1.TryGetValue(out var decrypted1) && apiKey2.TryGetValue(out var decrypted2)) + { + decryptedKeys = (decrypted1, decrypted2); + return true; + } + + decryptedKeys = ("", ""); + return false; + } + } + + [Serializable] + public class ApiKeyDecryptException : Exception + { + public ApiKeyDecryptException() { } + public ApiKeyDecryptException(string message) : base(message) { } + public ApiKeyDecryptException(string message, Exception innerException) : base(message, innerException) { } + protected ApiKeyDecryptException(SerializationInfo info, StreamingContext context) : base(info, context) { } + } +} diff --git a/OpenTween/ApplicationSettings.cs b/OpenTween/ApplicationSettings.cs index e7a29730d..e65f3bcf5 100644 --- a/OpenTween/ApplicationSettings.cs +++ b/OpenTween/ApplicationSettings.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; @@ -104,15 +105,27 @@ internal static class ApplicationSettings /// public static readonly string VersionInfoUrl = "https://www.opentween.org/status/version.txt"; + //===================================================================== + // 暗号化キー + + /// + /// APIキーの暗号化・復号に使用するパスワード + /// + public static readonly string EncryptionPassword = ApplicationName; + //===================================================================== // Twitter - // https://dev.twitter.com/ から取得できます。 + // https://developer.twitter.com/ から取得できます。 + + /// + /// Twitter API Key + /// + public static readonly ApiKey TwitterConsumerKey = ApiKey.Create("zIoJPq3FsuViPTAs89FetDHYz"); /// - /// Twitter コンシューマーキー + /// Twitter API Key Secret /// - public const string TwitterConsumerKey = "zIoJPq3FsuViPTAs89FetDHYz"; - public const string TwitterConsumerSecret = "prTAs2fqLv12nHxlMoLQZT8AkpZt0yYb8A7ktGS2VYeRj0TddS"; + public static readonly ApiKey TwitterConsumerSecret = ApiKey.Create("prTAs2fqLv12nHxlMoLQZT8AkpZt0yYb8A7ktGS2VYeRj0TddS"); //===================================================================== // Foursquare @@ -121,12 +134,12 @@ internal static class ApplicationSettings /// /// Foursquare Client Id /// - public const string FoursquareClientId = "5H3K5YQPT55DNQUFEOAJFNJA5D01ZJGO2ITEAJ3ASRIDONUB"; + public static readonly ApiKey FoursquareClientId = ApiKey.Create("5H3K5YQPT55DNQUFEOAJFNJA5D01ZJGO2ITEAJ3ASRIDONUB"); /// /// Foursquare Client Secret /// - public const string FoursquareClientSecret = "JFRHP1L451M3AEPF11UZLTIIUZCZTZRVHVOWB5TQ0AJOVPBB"; + public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("JFRHP1L451M3AEPF11UZLTIIUZCZTZRVHVOWB5TQ0AJOVPBB"); //===================================================================== // bit.ly @@ -135,12 +148,12 @@ internal static class ApplicationSettings /// /// bit.ly Client ID /// - public const string BitlyClientId = "ddab8ec50f4459c315cbde9d923cf490923b6d2e"; + public static readonly ApiKey BitlyClientId = ApiKey.Create("ddab8ec50f4459c315cbde9d923cf490923b6d2e"); /// /// bit.ly Client Secret /// - public const string BitlyClientSecret = "485c9d03dd264f8eeb4fc65d38e2762c4420cee7"; + public static readonly ApiKey BitlyClientSecret = ApiKey.Create("485c9d03dd264f8eeb4fc65d38e2762c4420cee7"); //===================================================================== // TINAMI @@ -149,7 +162,7 @@ internal static class ApplicationSettings /// /// TINAMI APIキー /// - public const string TINAMIApiKey = "4f48bb4858d36"; + public static readonly ApiKey TINAMIApiKey = ApiKey.Create("4f48bb4858d36"); //===================================================================== // Microsoft Translator API (Cognitive Service) @@ -158,7 +171,7 @@ internal static class ApplicationSettings /// /// Translator Text API Subscription Key /// - public readonly static string TranslatorSubscriptionKey = "6c47d2ea341148bf856bdbfafd429db7"; + public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("6c47d2ea341148bf856bdbfafd429db7"); //===================================================================== // Imgur @@ -167,12 +180,12 @@ internal static class ApplicationSettings /// /// Imgur Client ID /// - public readonly static string ImgurClientID = "a5fff36fb83568c"; + public static readonly ApiKey ImgurClientId = ApiKey.Create("a5fff36fb83568c"); /// /// Imgur Client Secret /// - public readonly static string ImgurClientSecret = "af5d668a9aa83b34a8f0f735e12073edafbc9a5d"; + public static readonly ApiKey ImgurClientSecret = ApiKey.Create("af5d668a9aa83b34a8f0f735e12073edafbc9a5d"); //===================================================================== // Mobypicture @@ -181,7 +194,7 @@ internal static class ApplicationSettings /// /// Mobypicture Developer Key /// - public readonly static string MobypictureKey = "quPWTX0UrPHxqdH7"; + public static readonly ApiKey MobypictureKey = ApiKey.Create("quPWTX0UrPHxqdH7"); //===================================================================== // Tumblr @@ -190,6 +203,6 @@ internal static class ApplicationSettings /// /// Tumblr OAuth Consumer Key /// - public readonly static string TumblrConsumerKey = "Nsk62V6wMIqVNbiGyN0g3aDGBlgU7Fcb9GJ8Se0z2MUDHAY15l"; + public static readonly ApiKey TumblrConsumerKey = ApiKey.Create("Nsk62V6wMIqVNbiGyN0g3aDGBlgU7Fcb9GJ8Se0z2MUDHAY15l"); } } diff --git a/OpenTween/Bing.cs b/OpenTween/Bing.cs index e043527a1..4aac36d61 100644 --- a/OpenTween/Bing.cs +++ b/OpenTween/Bing.cs @@ -170,12 +170,7 @@ public class Bing private readonly MicrosoftTranslatorApi translatorApi; public Bing() - : this(null) - { - } - - public Bing(HttpClient? http) - => this.translatorApi = new MicrosoftTranslatorApi(http); + => this.translatorApi = new MicrosoftTranslatorApi(); /// /// Microsoft Translator API を使用した翻訳を非同期に行います diff --git a/OpenTween/Connection/OAuthEchoHandler.cs b/OpenTween/Connection/OAuthEchoHandler.cs index 7fde554f4..6bf4c7d3b 100644 --- a/OpenTween/Connection/OAuthEchoHandler.cs +++ b/OpenTween/Connection/OAuthEchoHandler.cs @@ -53,7 +53,7 @@ protected override Task SendAsync(HttpRequestMessage reques } public static OAuthEchoHandler CreateHandler(HttpMessageHandler innerHandler, Uri authServiceProvider, - string consumerKey, string consumerSecret, string accessToken, string accessSecret, Uri? realm = null) + ApiKey consumerKey, ApiKey consumerSecret, string accessToken, string accessSecret, Uri? realm = null) { var credential = OAuthUtility.CreateAuthorization("GET", authServiceProvider, null, consumerKey, consumerSecret, accessToken, accessSecret, realm?.AbsoluteUri); diff --git a/OpenTween/Connection/OAuthHandler.cs b/OpenTween/Connection/OAuthHandler.cs index 78175dc6d..b302a3585 100644 --- a/OpenTween/Connection/OAuthHandler.cs +++ b/OpenTween/Connection/OAuthHandler.cs @@ -38,12 +38,12 @@ namespace OpenTween.Connection /// public class OAuthHandler : DelegatingHandler { - public string ConsumerKey { get; } - public string ConsumerSecret { get; } + public ApiKey ConsumerKey { get; } + public ApiKey ConsumerSecret { get; } public string AccessToken { get; } public string AccessSecret { get; } - public OAuthHandler(HttpMessageHandler innerHandler, string consumerKey, string consumerSecret, string accessToken, string accessSecret) + public OAuthHandler(HttpMessageHandler innerHandler, ApiKey consumerKey, ApiKey consumerSecret, string accessToken, string accessSecret) : base(innerHandler) { this.ConsumerKey = consumerKey; diff --git a/OpenTween/Connection/OAuthUtility.cs b/OpenTween/Connection/OAuthUtility.cs index 8d4510690..22aa27810 100644 --- a/OpenTween/Connection/OAuthUtility.cs +++ b/OpenTween/Connection/OAuthUtility.cs @@ -56,7 +56,7 @@ public static class OAuthUtility /// アクセストークンシークレット。認証処理では空文字列 /// realm (必要な場合のみ) public static string CreateAuthorization(string httpMethod, Uri requestUri, IEnumerable>? query, - string consumerKey, string consumerSecret, string token, string tokenSecret, + ApiKey consumerKey, ApiKey consumerSecret, string token, string tokenSecret, string? realm = null) { // OAuth共通情報取得 @@ -86,11 +86,11 @@ public static string CreateAuthorization(string httpMethod, Uri requestUri, IEnu ///
/// アクセストークン、もしくはリクエストトークン。未取得なら空文字列 /// OAuth情報のディクショナリ - public static Dictionary GetOAuthParameter(string consumerKey, string token) + public static Dictionary GetOAuthParameter(ApiKey consumerKey, string token) { var parameter = new Dictionary { - ["oauth_consumer_key"] = consumerKey, + ["oauth_consumer_key"] = consumerKey.Value, ["oauth_signature_method"] = "HMAC-SHA1", ["oauth_timestamp"] = DateTimeUtc.Now.ToUnixTime().ToString(), // epoch秒 ["oauth_nonce"] = NonceRandom.Next(123400, 9999999).ToString(), @@ -109,7 +109,7 @@ public static Dictionary GetOAuthParameter(string consumerKey, s /// アクセス先Uri /// クエリ、もしくはPOSTデータ /// 署名文字列 - public static string CreateSignature(string consumerSecret, string? tokenSecret, string method, Uri uri, Dictionary parameter) + public static string CreateSignature(ApiKey consumerSecret, string? tokenSecret, string method, Uri uri, Dictionary parameter) { // パラメタをソート済みディクショナリに詰替(OAuthの仕様) var sorted = new SortedDictionary(parameter); @@ -120,7 +120,7 @@ public static string CreateSignature(string consumerSecret, string? tokenSecret, // 署名のベース文字列生成(&区切り)。クエリ形式文字列は再エンコードする var signatureBase = string.Format("{0}&{1}&{2}", method, MyCommon.UrlEncode(url), MyCommon.UrlEncode(paramString)); // 署名鍵の文字列をコンシューマー秘密鍵とアクセストークン秘密鍵から生成(&区切り。アクセストークン秘密鍵なくても&残すこと) - var key = MyCommon.UrlEncode(consumerSecret) + "&"; + var key = MyCommon.UrlEncode(consumerSecret.Value) + "&"; if (!MyCommon.IsNullOrEmpty(tokenSecret)) key += MyCommon.UrlEncode(tokenSecret); // 鍵生成&署名生成 diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index f603554de..f42d93df0 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -58,8 +58,13 @@ public static string RestApiHost internal HttpClient httpUpload = null!; internal HttpClient httpStreaming = null!; - public TwitterApiConnection(string accessToken, string accessSecret) + private readonly ApiKey consumerKey; + private readonly ApiKey consumerSecret; + + public TwitterApiConnection(ApiKey consumerKey, ApiKey consumerSecret, string accessToken, string accessSecret) { + this.consumerKey = consumerKey; + this.consumerSecret = consumerSecret; this.AccessToken = accessToken; this.AccessSecret = accessSecret; @@ -69,12 +74,12 @@ public TwitterApiConnection(string accessToken, string accessSecret) private void InitializeHttpClients() { - this.http = InitializeHttpClient(this.AccessToken, this.AccessSecret); + this.http = InitializeHttpClient(this.consumerKey, this.consumerSecret, this.AccessToken, this.AccessSecret); - this.httpUpload = InitializeHttpClient(this.AccessToken, this.AccessSecret); + this.httpUpload = InitializeHttpClient(this.consumerKey, this.consumerSecret, this.AccessToken, this.AccessSecret); this.httpUpload.Timeout = Networking.UploadImageTimeout; - this.httpStreaming = InitializeHttpClient(this.AccessToken, this.AccessSecret, disableGzip: true); + this.httpStreaming = InitializeHttpClient(this.consumerKey, this.consumerSecret, this.AccessToken, this.AccessSecret, disableGzip: true); this.httpStreaming.Timeout = Timeout.InfiniteTimeSpan; } @@ -433,8 +438,7 @@ public OAuthEchoHandler CreateOAuthEchoHandler(Uri authServiceProvider, Uri? rea var uri = new Uri(RestApiBase, authServiceProvider); return OAuthEchoHandler.CreateHandler(Networking.CreateHttpClientHandler(), uri, - ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret, - this.AccessToken, this.AccessSecret, realm); + this.consumerKey, this.consumerSecret, this.AccessToken, this.AccessSecret, realm); } public void Dispose() @@ -465,13 +469,16 @@ protected virtual void Dispose(bool disposing) private void Networking_WebProxyChanged(object sender, EventArgs e) => this.InitializeHttpClients(); - public static async Task<(string Token, string TokenSecret)> GetRequestTokenAsync() + public static Task<(string Token, string TokenSecret)> GetRequestTokenAsync() + => GetRequestTokenAsync(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); + + public static async Task<(string Token, string TokenSecret)> GetRequestTokenAsync(ApiKey consumerKey, ApiKey consumerSecret) { var param = new Dictionary { ["oauth_callback"] = "oob", }; - var response = await GetOAuthTokenAsync(new Uri("https://api.twitter.com/oauth/request_token"), param, oauthToken: null) + var response = await GetOAuthTokenAsync(new Uri("https://api.twitter.com/oauth/request_token"), param, consumerKey, consumerSecret, oauthToken: null) .ConfigureAwait(false); return (response["oauth_token"], response["oauth_token_secret"]); @@ -490,26 +497,29 @@ public static Uri GetAuthorizeUri((string Token, string TokenSecret) requestToke return new Uri("https://api.twitter.com/oauth/authorize?" + MyCommon.BuildQueryString(param)); } - public static async Task> GetAccessTokenAsync((string Token, string TokenSecret) requestToken, string verifier) + public static Task> GetAccessTokenAsync((string Token, string TokenSecret) requestToken, string verifier) + => GetAccessTokenAsync(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret, requestToken, verifier); + + public static async Task> GetAccessTokenAsync(ApiKey consumerKey, ApiKey consumerSecret, (string Token, string TokenSecret) requestToken, string verifier) { var param = new Dictionary { ["oauth_verifier"] = verifier, }; - var response = await GetOAuthTokenAsync(new Uri("https://api.twitter.com/oauth/access_token"), param, requestToken) + var response = await GetOAuthTokenAsync(new Uri("https://api.twitter.com/oauth/access_token"), param, consumerKey, consumerSecret, requestToken) .ConfigureAwait(false); return response; } private static async Task> GetOAuthTokenAsync(Uri uri, IDictionary param, - (string Token, string TokenSecret)? oauthToken) + ApiKey consumerKey, ApiKey consumerSecret, (string Token, string TokenSecret)? oauthToken) { HttpClient authorizeClient; if (oauthToken != null) - authorizeClient = InitializeHttpClient(oauthToken.Value.Token, oauthToken.Value.TokenSecret); + authorizeClient = InitializeHttpClient(consumerKey, consumerSecret, oauthToken.Value.Token, oauthToken.Value.TokenSecret); else - authorizeClient = InitializeHttpClient("", ""); + authorizeClient = InitializeHttpClient(consumerKey, consumerSecret, "", ""); var requestUri = new Uri(uri, "?" + MyCommon.BuildQueryString(param)); @@ -541,7 +551,7 @@ private static async Task> GetOAuthTokenAsync(Uri ur } } - private static HttpClient InitializeHttpClient(string accessToken, string accessSecret, bool disableGzip = false) + private static HttpClient InitializeHttpClient(ApiKey consumerKey, ApiKey consumerSecret, string accessToken, string accessSecret, bool disableGzip = false) { var innerHandler = Networking.CreateHttpClientHandler(); innerHandler.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); @@ -549,9 +559,7 @@ private static HttpClient InitializeHttpClient(string accessToken, string access if (disableGzip) innerHandler.AutomaticDecompression = DecompressionMethods.None; - var handler = new OAuthHandler(innerHandler, - ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret, - accessToken, accessSecret); + var handler = new OAuthHandler(innerHandler, consumerKey, consumerSecret, accessToken, accessSecret); return Networking.CreateHttpClient(handler); } diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 94bfe47fc..355f72cc5 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -68,6 +68,7 @@ ApiInfoDialog.cs + diff --git a/OpenTween/Thumbnail/Services/FoursquareCheckin.cs b/OpenTween/Thumbnail/Services/FoursquareCheckin.cs index d37f7bec7..b195d9172 100644 --- a/OpenTween/Thumbnail/Services/FoursquareCheckin.cs +++ b/OpenTween/Thumbnail/Services/FoursquareCheckin.cs @@ -52,14 +52,20 @@ protected HttpClient http => this.localHttpClient ?? Networking.Http; private readonly HttpClient? localHttpClient; + private readonly ApiKey clientId; + private readonly ApiKey clientSecret; public FoursquareCheckin() - : this(null) + : this(null, ApplicationSettings.FoursquareClientId, ApplicationSettings.FoursquareClientSecret) { } - public FoursquareCheckin(HttpClient? http) - => this.localHttpClient = http; + public FoursquareCheckin(HttpClient? http, ApiKey clientId, ApiKey clientSecret) + { + this.localHttpClient = http; + this.clientId = clientId; + this.clientSecret = clientSecret; + } public override async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { @@ -96,6 +102,10 @@ public FoursquareCheckin(HttpClient? http) if (!match.Success) return null; + if (!(this.clientId, this.clientSecret).TryGetValue(out var keyPair)) + return null; + + var (clientId, clientSecret) = keyPair; var checkinIdGroup = match.Groups["checkin_id"]; try @@ -105,8 +115,8 @@ public FoursquareCheckin(HttpClient? http) var query = new Dictionary { - ["client_id"] = ApplicationSettings.FoursquareClientId, - ["client_secret"] = ApplicationSettings.FoursquareClientSecret, + ["client_id"] = clientId, + ["client_secret"] = clientSecret, ["v"] = "20140419", // https://developer.foursquare.com/overview/versioning ["shortId"] = checkinIdGroup.Value, @@ -140,6 +150,10 @@ public FoursquareCheckin(HttpClient? http) if (!match.Success) return null; + if (!(this.clientId, this.clientSecret).TryGetValue(out var keyPair)) + return null; + + var (clientId, clientSecret) = keyPair; var checkinIdGroup = match.Groups["checkin_id"]; var signatureGroup = match.Groups["signature"]; @@ -150,8 +164,8 @@ public FoursquareCheckin(HttpClient? http) var query = new Dictionary { - ["client_id"] = ApplicationSettings.FoursquareClientId, - ["client_secret"] = ApplicationSettings.FoursquareClientSecret, + ["client_id"] = clientId, + ["client_secret"] = clientSecret, ["v"] = "20140419", // https://developer.foursquare.com/overview/versioning }; diff --git a/OpenTween/Thumbnail/Services/Tinami.cs b/OpenTween/Thumbnail/Services/Tinami.cs index de0979ecc..d0a4eaa57 100644 --- a/OpenTween/Thumbnail/Services/Tinami.cs +++ b/OpenTween/Thumbnail/Services/Tinami.cs @@ -45,15 +45,19 @@ class Tinami : IThumbnailService protected HttpClient http => this.localHttpClient ?? Networking.Http; + private readonly ApiKey apiKey; private readonly HttpClient? localHttpClient; public Tinami() - : this(null) + : this(ApplicationSettings.TINAMIApiKey, null) { } - public Tinami(HttpClient? http) - => this.localHttpClient = http; + public Tinami(ApiKey apiKey, HttpClient? http) + { + this.apiKey = apiKey; + this.localHttpClient = http; + } public override async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { @@ -61,11 +65,14 @@ public Tinami(HttpClient? http) if (!match.Success) return null; + if (!this.apiKey.TryGetValue(out var apiKey)) + return null; + var contentId = match.Groups["ContentId"].Value; try { - var xdoc = await this.FetchContentInfoApiAsync(contentId, token) + var xdoc = await this.FetchContentInfoApiAsync(apiKey, contentId, token) .ConfigureAwait(false); if (xdoc.XPathSelectElement("/rsp").Attribute("stat").Value != "ok") @@ -89,11 +96,11 @@ public Tinami(HttpClient? http) return null; } - protected virtual async Task FetchContentInfoApiAsync(string contentId, CancellationToken token) + protected virtual async Task FetchContentInfoApiAsync(string apiKey, string contentId, CancellationToken token) { var query = new Dictionary { - ["api_key"] = ApplicationSettings.TINAMIApiKey, + ["api_key"] = apiKey, ["cont_id"] = contentId, }; diff --git a/OpenTween/Thumbnail/Services/Tumblr.cs b/OpenTween/Thumbnail/Services/Tumblr.cs index 402edbd8c..f4db07faa 100644 --- a/OpenTween/Thumbnail/Services/Tumblr.cs +++ b/OpenTween/Thumbnail/Services/Tumblr.cs @@ -46,15 +46,19 @@ class Tumblr : IThumbnailService protected HttpClient http => this.localHttpClient ?? Networking.Http; + private readonly ApiKey tumblrConsumerKey; private readonly HttpClient? localHttpClient; public Tumblr() - : this(null) + : this(ApplicationSettings.TumblrConsumerKey, null) { } - public Tumblr(HttpClient? http) - => this.localHttpClient = http; + public Tumblr(ApiKey apiKey, HttpClient? http) + { + this.tumblrConsumerKey = apiKey; + this.localHttpClient = http; + } public override async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { @@ -62,6 +66,9 @@ public Tumblr(HttpClient? http) if (!match.Success) return null; + if (!this.tumblrConsumerKey.TryGetValue(out var apiKey)) + return null; + // 参照: http://www.tumblr.com/docs/en/api/v2#photo-posts var host = match.Groups["host"].Value; @@ -69,7 +76,7 @@ public Tumblr(HttpClient? http) var param = new Dictionary { - ["api_key"] = ApplicationSettings.TumblrConsumerKey, + ["api_key"] = apiKey, ["id"] = postId, }; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 51289fe06..0a9b99963 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -140,7 +140,7 @@ public partial class TweenMain : OTBaseForm private FormWindowState _formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する //twitter解析部 - private readonly TwitterApi twitterApi = new TwitterApi(); + private readonly TwitterApi twitterApi = new TwitterApi(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); private Twitter tw = null!; //Growl呼び出し部 diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index ec33d6da6..575cbd548 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -376,7 +376,7 @@ private async Task DoTranslation(string str) this.PostBrowser.DocumentText = this.Owner.createDetailHtml(translatedText); } - catch (HttpRequestException e) + catch (WebApiException e) { this.RaiseStatusChanged("Err:" + e.Message); } diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 52127465c..5c6db1afd 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -169,10 +169,6 @@ public class Twitter : IDisposable private long previousStatusId = -1L; - public Twitter() : this(new TwitterApi()) - { - } - public Twitter(TwitterApi api) { this.Api = api; From 20da24f86c53199b6ce1d6844ced836fd7290522 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 17 Jan 2022 01:58:09 +0900 Subject: [PATCH 037/402] =?UTF-8?q?API=E3=82=AD=E3=83=BC=E3=81=AE=E6=9A=97?= =?UTF-8?q?=E5=8F=B7=E5=8C=96=E3=82=92=E8=A1=8C=E3=81=86=E3=81=9F=E3=82=81?= =?UTF-8?q?=E3=81=AE=E3=83=80=E3=82=A4=E3=82=A2=E3=83=AD=E3=82=B0=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/EncryptApiKeyDialog.Designer.cs | 131 ++++++ OpenTween/EncryptApiKeyDialog.cs | 49 ++ OpenTween/EncryptApiKeyDialog.resx | 426 ++++++++++++++++++ OpenTween/OpenTween.csproj | 9 + .../Setting/Panel/CooperatePanel.Designer.cs | 10 + OpenTween/Setting/Panel/CooperatePanel.cs | 11 +- .../Setting/Panel/CooperatePanel.en.resx | 11 +- OpenTween/Setting/Panel/CooperatePanel.resx | 52 ++- 8 files changed, 680 insertions(+), 19 deletions(-) create mode 100644 OpenTween/EncryptApiKeyDialog.Designer.cs create mode 100644 OpenTween/EncryptApiKeyDialog.cs create mode 100644 OpenTween/EncryptApiKeyDialog.resx diff --git a/OpenTween/EncryptApiKeyDialog.Designer.cs b/OpenTween/EncryptApiKeyDialog.Designer.cs new file mode 100644 index 000000000..c8f90b724 --- /dev/null +++ b/OpenTween/EncryptApiKeyDialog.Designer.cs @@ -0,0 +1,131 @@ +namespace OpenTween +{ + partial class EncryptApiKeyDialog + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EncryptApiKeyDialog)); + this.label1 = new System.Windows.Forms.Label(); + this.textBoxPlainText = new System.Windows.Forms.TextBox(); + this.textBoxPassword = new System.Windows.Forms.TextBox(); + this.textBoxEncryptedText = new System.Windows.Forms.TextBox(); + this.label2 = new System.Windows.Forms.Label(); + this.label3 = new System.Windows.Forms.Label(); + this.buttonEncrypt = new System.Windows.Forms.Button(); + this.buttonClose = new System.Windows.Forms.Button(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); + this.tableLayoutPanel1.SuspendLayout(); + this.SuspendLayout(); + // + // label1 + // + resources.ApplyResources(this.label1, "label1"); + this.label1.Name = "label1"; + // + // textBoxPlainText + // + resources.ApplyResources(this.textBoxPlainText, "textBoxPlainText"); + this.textBoxPlainText.Name = "textBoxPlainText"; + // + // textBoxPassword + // + resources.ApplyResources(this.textBoxPassword, "textBoxPassword"); + this.textBoxPassword.Name = "textBoxPassword"; + this.textBoxPassword.ReadOnly = true; + // + // textBoxEncryptedText + // + resources.ApplyResources(this.textBoxEncryptedText, "textBoxEncryptedText"); + this.textBoxEncryptedText.Name = "textBoxEncryptedText"; + // + // label2 + // + resources.ApplyResources(this.label2, "label2"); + this.label2.Name = "label2"; + // + // label3 + // + resources.ApplyResources(this.label3, "label3"); + this.label3.Name = "label3"; + // + // buttonEncrypt + // + resources.ApplyResources(this.buttonEncrypt, "buttonEncrypt"); + this.tableLayoutPanel1.SetColumnSpan(this.buttonEncrypt, 2); + this.buttonEncrypt.Name = "buttonEncrypt"; + this.buttonEncrypt.UseVisualStyleBackColor = true; + this.buttonEncrypt.Click += new System.EventHandler(this.ButtonEncrypt_Click); + // + // buttonClose + // + resources.ApplyResources(this.buttonClose, "buttonClose"); + this.buttonClose.DialogResult = System.Windows.Forms.DialogResult.Cancel; + this.buttonClose.Name = "buttonClose"; + this.buttonClose.UseVisualStyleBackColor = true; + // + // tableLayoutPanel1 + // + resources.ApplyResources(this.tableLayoutPanel1, "tableLayoutPanel1"); + this.tableLayoutPanel1.Controls.Add(this.label2, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.buttonClose, 1, 4); + this.tableLayoutPanel1.Controls.Add(this.textBoxPlainText, 1, 0); + this.tableLayoutPanel1.Controls.Add(this.textBoxEncryptedText, 1, 3); + this.tableLayoutPanel1.Controls.Add(this.label3, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.buttonEncrypt, 0, 2); + this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.textBoxPassword, 1, 1); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + // + // EncryptApiKeyDialog + // + resources.ApplyResources(this, "$this"); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.CancelButton = this.buttonClose; + this.Controls.Add(this.tableLayoutPanel1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.Name = "EncryptApiKeyDialog"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.ResumeLayout(false); + + } + + #endregion + + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox textBoxPlainText; + private System.Windows.Forms.TextBox textBoxPassword; + private System.Windows.Forms.TextBox textBoxEncryptedText; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Button buttonEncrypt; + private System.Windows.Forms.Button buttonClose; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + } +} \ No newline at end of file diff --git a/OpenTween/EncryptApiKeyDialog.cs b/OpenTween/EncryptApiKeyDialog.cs new file mode 100644 index 000000000..cd5170f12 --- /dev/null +++ b/OpenTween/EncryptApiKeyDialog.cs @@ -0,0 +1,49 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace OpenTween +{ + public partial class EncryptApiKeyDialog : OTBaseForm + { + public EncryptApiKeyDialog() + { + this.InitializeComponent(); + this.textBoxPassword.Text = ApplicationSettings.EncryptionPassword; + } + + private void ButtonEncrypt_Click(object sender, EventArgs e) + { + this.textBoxEncryptedText.Text = ApiKey.Encrypt(ApplicationSettings.EncryptionPassword, this.textBoxPlainText.Text); + } + } +} diff --git a/OpenTween/EncryptApiKeyDialog.resx b/OpenTween/EncryptApiKeyDialog.resx new file mode 100644 index 000000000..2cffda287 --- /dev/null +++ b/OpenTween/EncryptApiKeyDialog.resx @@ -0,0 +1,426 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + Left, Right + + + + True + + + + 3, 33 + + + 105, 12 + + + 2 + + + 暗号化パスワード + + + label1 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 6 + + + Left, Right + + + 114, 5 + + + 3, 3, 3, 0 + + + 221, 19 + + + 1 + + + textBoxPlainText + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 2 + + + Left, Right + + + 114, 31 + + + 3, 3, 3, 0 + + + 221, 19 + + + 3 + + + textBoxPassword + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 7 + + + Left, Right + + + 114, 83 + + + 3, 3, 3, 0 + + + 221, 19 + + + 6 + + + textBoxEncryptedText + + + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 3 + + + Left, Right + + + True + + + 3, 7 + + + 105, 12 + + + 0 + + + 暗号化する文字列 + + + label2 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 0 + + + Left, Right + + + True + + + 3, 85 + + + 105, 12 + + + 5 + + + 暗号化された文字列 + + + label3 + + + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 4 + + + Top, Bottom, Left, Right + + + True + + + GrowAndShrink + + + Top, Bottom, Left, Right + + + 2 + + + Top, Bottom, Right + + + True + + + GrowAndShrink + + + 250, 107 + + + 3, 3, 3, 0 + + + 10, 0, 10, 0 + + + 85, 23 + + + 7 + + + 閉じる (&C) + + + buttonClose + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 1 + + + 12, 9 + + + 3, 0, 3, 3 + + + 5 + + + 338, 130 + + + 0 + + + tableLayoutPanel1 + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label2" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonClose" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textBoxPlainText" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textBoxEncryptedText" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label3" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonEncrypt" Row="2" RowSpan="1" Column="0" ColumnSpan="2" /><Control Name="label1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textBoxPassword" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0" /><Rows Styles="Percent,20,Percent,20,Percent,20,Percent,20,Percent,20" /></TableLayoutSettings> + + + 3, 55 + + + 3, 3, 3, 0 + + + 332, 23 + + + 4 + + + 暗号化 + + + buttonEncrypt + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + tableLayoutPanel1 + + + 5 + + + True + + + 96, 96 + + + 362, 151 + + + CenterParent + + + APIキー暗号化 + + + EncryptApiKeyDialog + + + OpenTween.OTBaseForm, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null + + \ No newline at end of file diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 355f72cc5..523a03db2 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -134,6 +134,12 @@ + + Form + + + EncryptApiKeyDialog.cs + Form @@ -471,6 +477,9 @@ AuthDialog.cs + + EncryptApiKeyDialog.cs + EventViewerDialog.cs diff --git a/OpenTween/Setting/Panel/CooperatePanel.Designer.cs b/OpenTween/Setting/Panel/CooperatePanel.Designer.cs index 36791315b..2cdb010ab 100644 --- a/OpenTween/Setting/Panel/CooperatePanel.Designer.cs +++ b/OpenTween/Setting/Panel/CooperatePanel.Designer.cs @@ -45,6 +45,7 @@ private void InitializeComponent() this.CheckNicoms = new System.Windows.Forms.CheckBox(); this.EnableImgAzyobuziNetCheckBox = new System.Windows.Forms.CheckBox(); this.ImgAzyobuziNetDisabledInDMCheckBox = new System.Windows.Forms.CheckBox(); + this.EncryptApiKeyButton = new System.Windows.Forms.Button(); this.MapThumbnailGroupBox.SuspendLayout(); this.SuspendLayout(); // @@ -278,10 +279,18 @@ private void InitializeComponent() this.ImgAzyobuziNetDisabledInDMCheckBox.Name = "ImgAzyobuziNetDisabledInDMCheckBox"; this.ImgAzyobuziNetDisabledInDMCheckBox.UseVisualStyleBackColor = true; // + // EncryptApiKeyButton + // + resources.ApplyResources(this.EncryptApiKeyButton, "EncryptApiKeyButton"); + this.EncryptApiKeyButton.Name = "EncryptApiKeyButton"; + this.EncryptApiKeyButton.UseVisualStyleBackColor = true; + this.EncryptApiKeyButton.Click += new System.EventHandler(this.EncryptApiKeyButton_Click); + // // CooperatePanel // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.Controls.Add(this.EncryptApiKeyButton); this.Controls.Add(this.ImgAzyobuziNetDisabledInDMCheckBox); this.Controls.Add(this.EnableImgAzyobuziNetCheckBox); this.Controls.Add(this.MapThumbnailGroupBox); @@ -316,5 +325,6 @@ private void InitializeComponent() internal System.Windows.Forms.ComboBox MapThumbnailProviderComboBox; internal System.Windows.Forms.CheckBox EnableImgAzyobuziNetCheckBox; internal System.Windows.Forms.CheckBox ImgAzyobuziNetDisabledInDMCheckBox; + private System.Windows.Forms.Button EncryptApiKeyButton; } } diff --git a/OpenTween/Setting/Panel/CooperatePanel.cs b/OpenTween/Setting/Panel/CooperatePanel.cs index 1a9586948..db3f6ca3b 100644 --- a/OpenTween/Setting/Panel/CooperatePanel.cs +++ b/OpenTween/Setting/Panel/CooperatePanel.cs @@ -41,7 +41,10 @@ namespace OpenTween.Setting.Panel public partial class CooperatePanel : SettingPanelBase { public CooperatePanel() - => this.InitializeComponent(); + { + this.InitializeComponent(); + this.EncryptApiKeyButton.Visible = MyCommon.DebugBuild; + } public void LoadConfig(SettingCommon settingCommon) { @@ -79,5 +82,11 @@ private void UserAppointUrlText_Validating(object sender, CancelEventArgs e) private void EnableImgAzyobuziNetCheckBox_CheckedChanged(object sender, EventArgs e) => this.ImgAzyobuziNetDisabledInDMCheckBox.Enabled = this.EnableImgAzyobuziNetCheckBox.Checked; + + private void EncryptApiKeyButton_Click(object sender, EventArgs e) + { + using var dialog = new EncryptApiKeyDialog(); + dialog.ShowDialog(this.ParentForm); + } } } diff --git a/OpenTween/Setting/Panel/CooperatePanel.en.resx b/OpenTween/Setting/Panel/CooperatePanel.en.resx index 57fb83092..ff8a68a85 100644 --- a/OpenTween/Setting/Panel/CooperatePanel.en.resx +++ b/OpenTween/Setting/Panel/CooperatePanel.en.resx @@ -154,13 +154,10 @@ Shorten nicovideo urls by nico.ms - - 107, 12 + + 154, 23 - - 86, 12 - - - Your secret key + + API Key Encryption \ No newline at end of file diff --git a/OpenTween/Setting/Panel/CooperatePanel.resx b/OpenTween/Setting/Panel/CooperatePanel.resx index abbd0b792..f899bfc73 100644 --- a/OpenTween/Setting/Panel/CooperatePanel.resx +++ b/OpenTween/Setting/Panel/CooperatePanel.resx @@ -117,21 +117,20 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenStreetMap Google Maps + 102, 22 121, 20 + 1 @@ -150,6 +149,7 @@ True + NoControl @@ -355,7 +355,7 @@ $this - 2 + 3 True @@ -385,7 +385,7 @@ $this - 3 + 4 218, 102 @@ -406,7 +406,7 @@ $this - 4 + 5 Afrikaans @@ -799,7 +799,7 @@ $this - 5 + 6 True @@ -829,7 +829,7 @@ $this - 6 + 7 True @@ -859,7 +859,7 @@ $this - 7 + 8 True @@ -886,7 +886,7 @@ $this - 1 + 2 True @@ -916,6 +916,36 @@ $this + 1 + + + True + + + 23, 293 + + + 20, 0, 20, 0 + + + 135, 23 + + + 8 + + + APIキー暗号化 + + + EncryptApiKeyButton + + + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + 0 @@ -928,6 +958,6 @@ CooperatePanel - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null \ No newline at end of file From c6526f63f91f22d1e6eb21baa0065dc10660e5f5 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 26 Jan 2022 01:59:29 +0900 Subject: [PATCH 038/402] =?UTF-8?q?YouTube=E3=81=AE=E3=82=B5=E3=83=A0?= =?UTF-8?q?=E3=83=8D=E3=82=A4=E3=83=AB=E3=82=92=E8=A1=A8=E7=A4=BA=E3=81=99?= =?UTF-8?q?=E3=82=8BURL=E3=81=AE=E3=83=91=E3=82=BF=E3=83=BC=E3=83=B3?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Thumbnail/Services/YoutubeTest.cs | 44 +++++++++++++++++++ OpenTween/Resources/ChangeLog.txt | 2 +- OpenTween/Thumbnail/Services/Youtube.cs | 34 +++++++++++--- 3 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs diff --git a/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs b/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs new file mode 100644 index 000000000..3d39b7aca --- /dev/null +++ b/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs @@ -0,0 +1,44 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween.Thumbnail.Services +{ + public class YoutubeTest + { + [Theory] + [InlineData("https://www.youtube.com/watch?v=aaaaa", "aaaaa")] + [InlineData("https://www.youtube.com/watch?v=aaaaa#hoge", "aaaaa")] + [InlineData("https://www.youtube.com/watch?feature=youtu.be&v=aaaaa&app=desktop", "aaaaa")] + [InlineData("https://m.youtube.com/watch?v=aaaaa", "aaaaa")] + [InlineData("https://youtu.be/aaaaa", "aaaaa")] + [InlineData("https://youtu.be/aaaaa?t=123", "aaaaa")] + [InlineData("https://www.youtube.com/channel/aaaaa", null)] // チャンネルページ + public void GetVideoIdFromUrl_Test(string testUrl, string expected) + => Assert.Equal(expected, Youtube.GetVideoIdFromUrl(testUrl)); + } +} diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 6bc611b27..05bdf5d4b 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,7 +2,7 @@ ==== Ver 2.4.4-dev(2019/xx/xx) * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 - * CHG: Instagramのサムネイルを表示するURLのパターンを追加 + * CHG: Instagram, Youtubeのサムネイルを表示するURLのパターンを追加 * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) diff --git a/OpenTween/Thumbnail/Services/Youtube.cs b/OpenTween/Thumbnail/Services/Youtube.cs index 181f8a5bc..88cc6e209 100644 --- a/OpenTween/Thumbnail/Services/Youtube.cs +++ b/OpenTween/Thumbnail/Services/Youtube.cs @@ -30,10 +30,11 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; +using System.Web; using System.Xml; -using System.Text.RegularExpressions; using OpenTween.Models; namespace OpenTween.Thumbnail.Services @@ -41,17 +42,16 @@ namespace OpenTween.Thumbnail.Services class Youtube : IThumbnailService { public static readonly Regex UrlPatternRegex = - new Regex(@"^https?://(?:((?:www|m)\.youtube\.com)|(youtu\.be))/(watch\?v=)?(?([\w\-]+))"); + new Regex(@"^https?://(?:www\.youtube\.com|m\.youtube\.com|youtu\.be)/"); public override Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { return Task.Run(() => { - var match = Youtube.UrlPatternRegex.Match(url); - if (!match.Success) + var videoId = Youtube.GetVideoIdFromUrl(url); + if (videoId == null) return null; - var videoId = match.Groups["videoid"].Value; var imgUrl = "https://i.ytimg.com/vi/" + videoId + "/hqdefault.jpg"; return new ThumbnailInfo @@ -63,5 +63,29 @@ class Youtube : IThumbnailService }; }, token); } + + public static string? GetVideoIdFromUrl(string urlStr) + { + if (!Youtube.UrlPatternRegex.IsMatch(urlStr)) + return null; + + var url = new Uri(urlStr); + switch (url.Host) + { + case "www.youtube.com": + case "m.youtube.com": + { + if (url.AbsolutePath != "/watch") + return null; + + var query = HttpUtility.ParseQueryString(url.Query); + return query["v"]; + } + case "youtu.be": + return url.AbsolutePath.Substring(1); + default: + return null; + } + } } } From b9d74f88001be0327ebe4af2b831dab2949ea831 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 28 Jan 2022 00:27:53 +0900 Subject: [PATCH 039/402] =?UTF-8?q?YouTube=E3=81=AE=E3=82=B5=E3=83=A0?= =?UTF-8?q?=E3=83=8D=E3=82=A4=E3=83=AB=E3=82=92=E8=A1=A8=E7=A4=BA=E3=81=99?= =?UTF-8?q?=E3=82=8BURL=E3=81=AE=E3=83=91=E3=82=BF=E3=83=BC=E3=83=B3?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0=20(thx=20@Hawklaver!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Thumbnail/Services/YoutubeTest.cs | 13 ++++++-- OpenTween/Resources/ChangeLog.txt | 3 +- OpenTween/Thumbnail/Services/Youtube.cs | 33 +++---------------- 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs b/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs index 3d39b7aca..4d4b481bb 100644 --- a/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/YoutubeTest.cs @@ -35,10 +35,19 @@ public class YoutubeTest [InlineData("https://www.youtube.com/watch?v=aaaaa#hoge", "aaaaa")] [InlineData("https://www.youtube.com/watch?feature=youtu.be&v=aaaaa&app=desktop", "aaaaa")] [InlineData("https://m.youtube.com/watch?v=aaaaa", "aaaaa")] + [InlineData("https://gaming.youtube.com/watch?v=aaaaa", "aaaaa")] + [InlineData("https://music.youtube.com/watch?v=aaaaa", "aaaaa")] + [InlineData("https://www.youtube.com/shorts/aaaaa", "aaaaa")] + [InlineData("https://www.youtube.com/embed/aaaaa", "aaaaa")] [InlineData("https://youtu.be/aaaaa", "aaaaa")] [InlineData("https://youtu.be/aaaaa?t=123", "aaaaa")] [InlineData("https://www.youtube.com/channel/aaaaa", null)] // チャンネルページ - public void GetVideoIdFromUrl_Test(string testUrl, string expected) - => Assert.Equal(expected, Youtube.GetVideoIdFromUrl(testUrl)); + public void UrlPatternRegex_Test(string testUrl, string expected) + { + var match = Youtube.UrlPatternRegex.Match(testUrl); + + var matchedVideoId = match.Success ? match.Groups["videoId"].Value : null; + Assert.Equal(expected, matchedVideoId); + } } } diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 05bdf5d4b..02a9533df 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,7 +2,8 @@ ==== Ver 2.4.4-dev(2019/xx/xx) * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 - * CHG: Instagram, Youtubeのサムネイルを表示するURLのパターンを追加 + * CHG: Instagramのサムネイルを表示するURLのパターンを追加 + * CHG: YouTubeのサムネイルを表示するURLのパターンを追加 (thx @Hawklaver!) * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) diff --git a/OpenTween/Thumbnail/Services/Youtube.cs b/OpenTween/Thumbnail/Services/Youtube.cs index 88cc6e209..d283b54b7 100644 --- a/OpenTween/Thumbnail/Services/Youtube.cs +++ b/OpenTween/Thumbnail/Services/Youtube.cs @@ -33,8 +33,6 @@ using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using System.Web; -using System.Xml; using OpenTween.Models; namespace OpenTween.Thumbnail.Services @@ -42,16 +40,17 @@ namespace OpenTween.Thumbnail.Services class Youtube : IThumbnailService { public static readonly Regex UrlPatternRegex = - new Regex(@"^https?://(?:www\.youtube\.com|m\.youtube\.com|youtu\.be)/"); + new Regex(@"^https?://(?:(?:(?:m|www|music|gaming)\.)?youtube\.com/(?:watch\?(?:[^#]*&)?v=|embed/|shorts/)|youtu\.be/)(?[\w\-]+)"); public override Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { return Task.Run(() => { - var videoId = Youtube.GetVideoIdFromUrl(url); - if (videoId == null) + var match = Youtube.UrlPatternRegex.Match(url); + if (!match.Success) return null; + var videoId = match.Groups["videoId"].Value; var imgUrl = "https://i.ytimg.com/vi/" + videoId + "/hqdefault.jpg"; return new ThumbnailInfo @@ -63,29 +62,5 @@ class Youtube : IThumbnailService }; }, token); } - - public static string? GetVideoIdFromUrl(string urlStr) - { - if (!Youtube.UrlPatternRegex.IsMatch(urlStr)) - return null; - - var url = new Uri(urlStr); - switch (url.Host) - { - case "www.youtube.com": - case "m.youtube.com": - { - if (url.AbsolutePath != "/watch") - return null; - - var query = HttpUtility.ParseQueryString(url.Query); - return query["v"]; - } - case "youtu.be": - return url.AbsolutePath.Substring(1); - default: - return null; - } - } } } From 060492c52ef3b983f95669a6d2a8e679c9da164b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 28 Jan 2022 03:07:40 +0900 Subject: [PATCH 040/402] =?UTF-8?q?ThrottlingTimer=E3=82=92ThrottleTimer/D?= =?UTF-8?q?ebounceTimer=E3=81=AB=E5=88=86=E5=89=B2=E3=83=BB=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=B3=E3=83=BC=E3=83=89=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/AsyncTimerTest.cs | 95 ++++ .../Connection/OAuthUtilityTest.cs | 3 +- OpenTween.Tests/DebounceTimerTest.cs | 408 ++++++++++++++++++ OpenTween.Tests/MockTimer.cs | 59 +++ OpenTween.Tests/TestUtils.cs | 17 + OpenTween.Tests/ThrottleTimerTest.cs | 194 +++++++++ OpenTween/AsyncTimer.cs | 16 +- OpenTween/DateTimeUtc.cs | 7 +- OpenTween/DebounceTimer.cs | 148 +++++++ OpenTween/OpenTween.csproj | 3 +- OpenTween/ThrottleTimer.cs | 123 ++++++ OpenTween/ThrottlingTimer.cs | 132 ------ OpenTween/Tween.cs | 28 +- 13 files changed, 1081 insertions(+), 152 deletions(-) create mode 100644 OpenTween.Tests/AsyncTimerTest.cs create mode 100644 OpenTween.Tests/DebounceTimerTest.cs create mode 100644 OpenTween.Tests/MockTimer.cs create mode 100644 OpenTween.Tests/ThrottleTimerTest.cs create mode 100644 OpenTween/DebounceTimer.cs create mode 100644 OpenTween/ThrottleTimer.cs delete mode 100644 OpenTween/ThrottlingTimer.cs diff --git a/OpenTween.Tests/AsyncTimerTest.cs b/OpenTween.Tests/AsyncTimerTest.cs new file mode 100644 index 000000000..1c7d130a2 --- /dev/null +++ b/OpenTween.Tests/AsyncTimerTest.cs @@ -0,0 +1,95 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween +{ + public class AsyncTimerTest + { + [Fact] + public async Task Change_FiringTest() + { + var tcs = new TaskCompletionSource(); + using var timer = new AsyncTimer(() => + { + tcs.SetResult(true); + return Task.CompletedTask; + }); + + var dueTime = TimeSpan.FromMilliseconds(15); + var period = TimeSpan.FromMilliseconds(100); + timer.Change(dueTime, period); + + var timeout = Task.Delay(1000); + Assert.NotEqual(timeout, await Task.WhenAny(tcs.Task, timeout)); + } + + [Fact] + public void Change_PropertiesTest() + { + using var timer = new AsyncTimer(() => Task.CompletedTask); + + Assert.Equal(Timeout.InfiniteTimeSpan, timer.DueTime); + Assert.Equal(Timeout.InfiniteTimeSpan, timer.Period); + + var dueTime = TimeSpan.FromMilliseconds(30); + var period = TimeSpan.FromMilliseconds(60); + timer.Change(dueTime, period); + + Assert.Equal(dueTime, timer.DueTime); + Assert.Equal(period, timer.Period); + } + + [Fact] + public async Task UnhandledException_Test() + { + var tcs = new TaskCompletionSource(); + EventHandler handler = (_, ev) => tcs.TrySetResult(ev.Exception); + + try + { + AsyncTimer.UnhandledException += handler; + + using var timer = new AsyncTimer(() => + { + throw new ApplicationException(); + }); + timer.Change(TimeSpan.FromMilliseconds(15), Timeout.InfiniteTimeSpan); + + var timeout = Task.Delay(1000); + Assert.NotEqual(timeout, await Task.WhenAny(tcs.Task, timeout)); + + Assert.IsType(tcs.Task.Result); + } + finally + { + AsyncTimer.UnhandledException -= handler; + } + } + } +} diff --git a/OpenTween.Tests/Connection/OAuthUtilityTest.cs b/OpenTween.Tests/Connection/OAuthUtilityTest.cs index 2079718f0..0c607b444 100644 --- a/OpenTween.Tests/Connection/OAuthUtilityTest.cs +++ b/OpenTween.Tests/Connection/OAuthUtilityTest.cs @@ -39,8 +39,7 @@ public void GetOAuthParameter_Test() Assert.Equal("ConsumerKey", param["oauth_consumer_key"]); Assert.Equal("HMAC-SHA1", param["oauth_signature_method"]); - var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0); - var unixTimeNow = Math.Ceiling((DateTime.UtcNow - unixEpoch).TotalSeconds); + var unixTimeNow = DateTimeUtc.Now.ToUnixTime(); Assert.InRange(long.Parse(param["oauth_timestamp"]), unixTimeNow - 5, unixTimeNow); Assert.NotEmpty(param["oauth_nonce"]); diff --git a/OpenTween.Tests/DebounceTimerTest.cs b/OpenTween.Tests/DebounceTimerTest.cs new file mode 100644 index 000000000..6949084b6 --- /dev/null +++ b/OpenTween.Tests/DebounceTimerTest.cs @@ -0,0 +1,408 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween +{ + public class DebounceTimerTest + { + private class TestDebounceTimer : DebounceTimer + { + public MockTimer mockTimer = new MockTimer(() => Task.CompletedTask); + + public TestDebounceTimer(Func timerCallback, TimeSpan interval, bool leading, bool trailing) + : base(timerCallback, interval, leading, trailing) + { + } + + protected override ITimer CreateTimer(Func callback) + => this.mockTimer = new MockTimer(callback); + } + + [Fact] + public async Task Callback_Debounce_Trailing_Test() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.MaxValue; + using var debouncing = new TestDebounceTimer(callback, interval, leading: false, trailing: true); + var mockTimer = debouncing.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:00 + await debouncing.Call(); + + // call + Assert.Equal(0, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:01:00 - 0:01:00 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await debouncing.Call(); + + // call (throttled) + Assert.Equal(0, count); + Assert.True(mockTimer.IsTimerRunning); + + // 0:02:00 - 0:02:00 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(0, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(1), mockTimer.DueTime); + + // 0:03:00 - 0:03:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); // invoked (trailing) + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public async Task Callback_Debounce_Trailing_CallOnceTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.MaxValue; + using var debouncing = new TestDebounceTimer(callback, interval, leading: false, trailing: true); + var mockTimer = debouncing.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:00 + await debouncing.Call(); + + // call + Assert.Equal(0, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:02:00 - 0:02:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); // invoked (trailing) + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public async Task Callback_Debounce_Trailing_ResumeTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.MaxValue; + using var debouncing = new TestDebounceTimer(callback, interval, leading: false, trailing: true); + var mockTimer = debouncing.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:00 + await debouncing.Call(); + + // call + Assert.Equal(0, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:02:00 - 0:02:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); // invoked (trailing) + Assert.False(mockTimer.IsTimerRunning); + + // 0:02:10 - 0:02:10 + await debouncing.Call(); + + // call + Assert.Equal(1, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:04:10 - 0:04:20 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(2, count); // invoked (trailing) + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public async Task Callback_Debounce_LeadingAndTrailing_Test() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.MaxValue; + using var debouncing = new TestDebounceTimer(callback, interval, leading: true, trailing: true); + var mockTimer = debouncing.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:10 + await debouncing.Call(); + + // call + Assert.Equal(1, count); // invoked (leading) + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:01:10 - 0:01:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await debouncing.Call(); + + // call (throttled) + Assert.Equal(1, count); + Assert.True(mockTimer.IsTimerRunning); + + // 0:02:10 - 0:02:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(1), mockTimer.DueTime); + + // 0:03:10 - 0:03:20 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(2, count); // invoked (trailing) + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public async Task Callback_Debounce_LeadingAndTrailing_CallOnceTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.MaxValue; + using var debouncing = new TestDebounceTimer(callback, interval, leading: true, trailing: true); + var mockTimer = debouncing.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:10 + await debouncing.Call(); + + // call + Assert.Equal(1, count); // invoked (leading) + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:02:10 - 0:02:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); // skip trailing + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public async Task Callback_Debounce_LeadingAndTrailing_ResumeTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.MaxValue; + using var debouncing = new TestDebounceTimer(callback, interval, leading: true, trailing: true); + var mockTimer = debouncing.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:10 + await debouncing.Call(); + + // call + Assert.Equal(1, count); // invoked (leading) + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:01:10 - 0:01:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await debouncing.Call(); + + // call (throttled) + Assert.Equal(1, count); + Assert.True(mockTimer.IsTimerRunning); + + // 0:02:10 - 0:02:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(1), mockTimer.DueTime); + + // 0:03:10 - 0:03:20 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(2, count); // invoked (trailing) + Assert.False(mockTimer.IsTimerRunning); + + // 0:03:20 - 0:03:30 + await debouncing.Call(); + + // call + Assert.Equal(3, count); // invoked (leading) + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:05:30 - 0:05:30 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(3, count); // skip trailing + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public async Task Callback_Debounce_SystemClockChangedTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 1, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.MaxValue; + using var debouncing = new TestDebounceTimer(callback, interval, leading: false, trailing: true); + var mockTimer = debouncing.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 1:00:00 - 1:00:00 + await debouncing.Call(); + + // call + Assert.Equal(0, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:00:00 + // システムの時刻が変更され1時間前に戻った場合 + TestUtils.DriftTime(TimeSpan.FromHours(-1)); + + // 0:02:00 - 0:02:00 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(0, count); + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:04:00 - 0:04:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); + Assert.False(mockTimer.IsTimerRunning); + } + } + } +} diff --git a/OpenTween.Tests/MockTimer.cs b/OpenTween.Tests/MockTimer.cs new file mode 100644 index 000000000..6be4ac5ad --- /dev/null +++ b/OpenTween.Tests/MockTimer.cs @@ -0,0 +1,59 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenTween +{ + public class MockTimer : ITimer + { + public bool IsTimerRunning { get; private set; } = false; + public TimeSpan DueTime { get; private set; } = Timeout.InfiniteTimeSpan; + public TimeSpan Period { get; private set; } = Timeout.InfiniteTimeSpan; + + private readonly Func callback; + + public MockTimer(Func callback) + => this.callback = callback; + + public void Change(TimeSpan dueTime, TimeSpan period) + { + this.IsTimerRunning = dueTime != Timeout.InfiniteTimeSpan; + this.DueTime = dueTime; + this.Period = period; + } + + public async Task Invoke() + { + this.IsTimerRunning = this.Period != Timeout.InfiniteTimeSpan; + await this.callback().ConfigureAwait(false); + } + + public void Dispose() + { + } + } +} diff --git a/OpenTween.Tests/TestUtils.cs b/OpenTween.Tests/TestUtils.cs index 210c19538..fd495e160 100644 --- a/OpenTween.Tests/TestUtils.cs +++ b/OpenTween.Tests/TestUtils.cs @@ -131,6 +131,23 @@ public static void Validate(T control) where T : Control TestUtils.FireEvent(control, "Validated"); } + + public static IDisposable FreezeTime(DateTimeUtc datetime) + { + DateTimeUtc.UseFakeNow = true; + DateTimeUtc.FakeNow = datetime; + DateTimeUtc.FakeNowDrift = TimeSpan.Zero; + return new RestoreFreezedTime(); + } + + public static void DriftTime(TimeSpan drift) + => DateTimeUtc.FakeNowDrift += drift; + + private sealed class RestoreFreezedTime : IDisposable + { + public void Dispose() + => DateTimeUtc.UseFakeNow = false; + } } } diff --git a/OpenTween.Tests/ThrottleTimerTest.cs b/OpenTween.Tests/ThrottleTimerTest.cs new file mode 100644 index 000000000..66a51226b --- /dev/null +++ b/OpenTween.Tests/ThrottleTimerTest.cs @@ -0,0 +1,194 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween +{ + public class ThrottleTimerTest + { + private class TestThrottleTimer : ThrottleTimer + { + public MockTimer mockTimer = new MockTimer(() => Task.CompletedTask); + + public TestThrottleTimer(Func timerCallback, TimeSpan interval) + : base(timerCallback, interval) + { + } + + protected override ITimer CreateTimer(Func callback) + => this.mockTimer = new MockTimer(callback); + } + + [Fact] + public async Task Callback_ThrottleTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.FromMinutes(2); + using var throttling = new TestThrottleTimer(callback, interval); + var mockTimer = throttling.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:10 + await throttling.Call(); + + // call (leading) + Assert.Equal(1, count); // invoked + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:01:10 - 0:01:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await throttling.Call(); + + // call (throttled) + Assert.Equal(1, count); + Assert.True(mockTimer.IsTimerRunning); + + // 0:02:10 - 0:02:20 + TestUtils.DriftTime(TimeSpan.FromMinutes(1)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(2, count); // invoked + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:04:20 - 0:04:20 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(2, count); + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public async Task Callback_CallOnceTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.FromMinutes(2); + using var throttling = new TestThrottleTimer(callback, interval); + var mockTimer = throttling.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:10 + await throttling.Call(); + + // call (leading) + Assert.Equal(1, count); // invoked + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:02:10 - 0:02:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public async Task Callback_ResumeTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + var count = 0; + Func callback = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + var interval = TimeSpan.FromMinutes(2); + var maxWait = TimeSpan.FromMinutes(2); + using var throttling = new TestThrottleTimer(callback, interval); + var mockTimer = throttling.mockTimer; + + Assert.Equal(0, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:00:00 - 0:00:10 + await throttling.Call(); + + // call (leading) + Assert.Equal(1, count); // invoked + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:02:10 - 0:02:10 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer + Assert.Equal(1, count); + Assert.False(mockTimer.IsTimerRunning); + + // 0:02:10 - 0:02:20 + await throttling.Call(); + + // call (leading) + Assert.Equal(2, count); // invoked + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + // 0:04:20 - 0:04:20 + TestUtils.DriftTime(TimeSpan.FromMinutes(2)); + await mockTimer.Invoke(); + + // timer (expired) + Assert.Equal(2, count); + Assert.False(mockTimer.IsTimerRunning); + } + } + } +} diff --git a/OpenTween/AsyncTimer.cs b/OpenTween/AsyncTimer.cs index ed2b7a56e..2b9ddb665 100644 --- a/OpenTween/AsyncTimer.cs +++ b/OpenTween/AsyncTimer.cs @@ -27,8 +27,11 @@ namespace OpenTween { - public sealed class AsyncTimer : IDisposable + public sealed class AsyncTimer : ITimer { + public TimeSpan DueTime { get; private set; } = Timeout.InfiniteTimeSpan; + public TimeSpan Period { get; private set; } = Timeout.InfiniteTimeSpan; + private readonly Func callback; private readonly Timer timer; @@ -53,9 +56,18 @@ private async void TimerCallback(object _) } public void Change(TimeSpan dueTime, TimeSpan period) - => this.timer.Change(dueTime, period); + { + this.DueTime = dueTime; + this.Period = period; + this.timer.Change(dueTime, period); + } public void Dispose() => this.timer.Dispose(); } + + public interface ITimer : IDisposable + { + void Change(TimeSpan dueTime, TimeSpan period); + } } diff --git a/OpenTween/DateTimeUtc.cs b/OpenTween/DateTimeUtc.cs index ffcac3665..0a324c52b 100644 --- a/OpenTween/DateTimeUtc.cs +++ b/OpenTween/DateTimeUtc.cs @@ -41,7 +41,12 @@ namespace OpenTween = new DateTimeUtc(1970, 1, 1, 0, 0, 0); public static DateTimeUtc Now - => new DateTimeUtc(DateTime.UtcNow); + => UseFakeNow ? FakeNow + FakeNowDrift : new DateTimeUtc(DateTime.UtcNow); + + // テストコード用 + internal static bool UseFakeNow = false; + internal static DateTimeUtc FakeNow = DateTimeUtc.MinValue; + internal static TimeSpan FakeNowDrift = TimeSpan.Zero; private readonly DateTime datetime; diff --git a/OpenTween/DebounceTimer.cs b/OpenTween/DebounceTimer.cs new file mode 100644 index 000000000..531853ac5 --- /dev/null +++ b/OpenTween/DebounceTimer.cs @@ -0,0 +1,148 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenTween +{ + /// + /// コールバック先の関数を 未満の頻度で呼ばないよう制御するタイマー + /// + /// + /// lodash の _.debounce() に相当する機能となっている + /// + public class DebounceTimer : IDisposable + { + private readonly ITimer debouncingTimer; + private readonly Func timerCallback; + private readonly object lockObject = new object(); + + private DateTimeUtc lastCall; + private bool calledSinceLastInvoke; + private bool refreshTimerEnabled; + + public TimeSpan Interval { get; } + public bool InvokeLeading { get; } + public bool InvokeTrailing { get; } + + public DebounceTimer(Func timerCallback, TimeSpan interval, bool leading, bool trailing) + { + this.timerCallback = timerCallback; + this.Interval = interval; + this.InvokeLeading = leading; + this.InvokeTrailing = trailing; + this.debouncingTimer = this.CreateTimer(this.Execute); + this.lastCall = DateTimeUtc.MinValue; + this.calledSinceLastInvoke = false; + this.refreshTimerEnabled = false; + } + + protected virtual ITimer CreateTimer(Func callback) + => new AsyncTimer(callback); + + public async Task Call() + { + bool startTimer, invoke; + lock (this.lockObject) + { + this.lastCall = DateTimeUtc.Now; + this.calledSinceLastInvoke = true; + if (this.refreshTimerEnabled) + { + startTimer = false; + invoke = false; + } + else + { + startTimer = true; + invoke = this.InvokeLeading; + this.refreshTimerEnabled = true; + } + } + + if (startTimer) + { + if (invoke) + await this.Invoke().ConfigureAwait(false); + + this.debouncingTimer.Change(dueTime: this.Interval, period: Timeout.InfiniteTimeSpan); + } + } + + private async Task Execute() + { + bool startTimer, invoke; + TimeSpan wait; + lock (this.lockObject) + { + var sinceLastCall = DateTimeUtc.Now - this.lastCall; + + if (sinceLastCall < TimeSpan.Zero) + { + // システムの時計が過去の時刻に変更された場合は無限ループを防ぐために lastCall をリセットする + this.lastCall = DateTimeUtc.Now; + sinceLastCall = TimeSpan.Zero; + } + + if (sinceLastCall < this.Interval) + { + startTimer = true; + wait = this.Interval - sinceLastCall; + invoke = false; + } + else + { + startTimer = false; + wait = TimeSpan.Zero; + invoke = this.InvokeTrailing && this.calledSinceLastInvoke; + this.refreshTimerEnabled = false; + } + } + + if (invoke) + await this.Invoke().ConfigureAwait(false); + + if (startTimer) + this.debouncingTimer.Change(dueTime: wait, period: Timeout.InfiniteTimeSpan); + } + + private async Task Invoke() + { + await Task.Run(async () => + { + lock (this.lockObject) + this.calledSinceLastInvoke = false; + + await this.timerCallback().ConfigureAwait(false); + }); + } + + public void Dispose() + => this.debouncingTimer.Dispose(); + + public static DebounceTimer Create(Func callback, TimeSpan wait, bool leading = false, bool trailing = true) + => new DebounceTimer(callback, wait, leading, trailing); + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 523a03db2..b4fbf607d 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -124,6 +124,7 @@ + @@ -194,7 +195,7 @@ - + diff --git a/OpenTween/ThrottleTimer.cs b/OpenTween/ThrottleTimer.cs new file mode 100644 index 000000000..ed63bb227 --- /dev/null +++ b/OpenTween/ThrottleTimer.cs @@ -0,0 +1,123 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2018 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace OpenTween +{ + /// + /// コールバック先の関数を 未満の頻度で呼ばないよう制御するタイマー + /// + /// + /// lodash の _.throttle() に相当する機能となっている + /// + public class ThrottleTimer : IDisposable + { + private readonly ITimer throttlingTimer; + private readonly Func timerCallback; + private readonly object lockObject = new object(); + + private bool calledSinceLastInvoke; + private bool refreshTimerEnabled; + + public TimeSpan Interval { get; } + + public ThrottleTimer(Func timerCallback, TimeSpan interval) + { + this.timerCallback = timerCallback; + this.Interval = interval; + this.throttlingTimer = this.CreateTimer(this.Execute); + this.calledSinceLastInvoke = false; + this.refreshTimerEnabled = false; + } + + protected virtual ITimer CreateTimer(Func callback) + => new AsyncTimer(callback); + + public async Task Call() + { + bool startTimer; + lock (this.lockObject) + { + this.calledSinceLastInvoke = true; + if (this.refreshTimerEnabled) + { + startTimer = false; + } + else + { + startTimer = true; + this.refreshTimerEnabled = true; + } + } + + if (startTimer) + { + await this.Invoke().ConfigureAwait(false); + this.throttlingTimer.Change(dueTime: this.Interval, period: Timeout.InfiniteTimeSpan); + } + } + + private async Task Execute() + { + bool invoke; + lock (this.lockObject) + { + if (this.calledSinceLastInvoke) + { + invoke = true; + } + else + { + invoke = false; + this.refreshTimerEnabled = false; + } + } + + if (invoke) + { + await this.Invoke().ConfigureAwait(false); + this.throttlingTimer.Change(dueTime: this.Interval, period: Timeout.InfiniteTimeSpan); + } + } + + private async Task Invoke() + { + await Task.Run(async () => + { + lock (this.lockObject) + this.calledSinceLastInvoke = false; + + await this.timerCallback().ConfigureAwait(false); + }); + } + + public void Dispose() + => this.throttlingTimer.Dispose(); + + public static ThrottleTimer Create(Func callback, TimeSpan wait) + => new ThrottleTimer(callback, wait); + } +} diff --git a/OpenTween/ThrottlingTimer.cs b/OpenTween/ThrottlingTimer.cs deleted file mode 100644 index 158222807..000000000 --- a/OpenTween/ThrottlingTimer.cs +++ /dev/null @@ -1,132 +0,0 @@ -// OpenTween - Client of Twitter -// Copyright (c) 2018 kim_upsilon (@kim_upsilon) -// All rights reserved. -// -// This file is part of OpenTween. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License -// for more details. -// -// You should have received a copy of the GNU General public License along -// with this program. If not, see , or write to -// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -// Boston, MA 02110-1301, USA. - -#nullable enable - -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace OpenTween -{ - /// - /// コールバック先の関数を 未満の頻度で呼ばないよう制御するタイマー - /// - public class ThrottlingTimer : IDisposable - { - private const int TIMER_DISABLED = 0; - private const int TIMER_ENABLED = 1; - - private readonly AsyncTimer throttlingTimer; - private readonly Func timerCallback; - - private long lastCalledTick; - private long lastInvokedTick; - private int refreshTimerEnabled = TIMER_DISABLED; - - public TimeSpan Interval { get; } - public TimeSpan MaxWait { get; } - public bool InvokeLeading { get; } - public bool InvokeTrailing { get; } - - private DateTimeUtc LastCalled - { - get => new DateTimeUtc(Interlocked.Read(ref this.lastCalledTick)); - set => Interlocked.Exchange(ref this.lastCalledTick, value.UtcTicks); - } - - private DateTimeUtc LastInvoked - { - get => new DateTimeUtc(Interlocked.Read(ref this.lastInvokedTick)); - set => Interlocked.Exchange(ref this.lastInvokedTick, value.UtcTicks); - } - - public ThrottlingTimer(Func timerCallback, TimeSpan interval, TimeSpan maxWait, bool leading, bool trailing) - { - this.timerCallback = timerCallback; - this.Interval = interval; - this.MaxWait = maxWait; - this.LastCalled = DateTimeUtc.MinValue; - this.LastInvoked = DateTimeUtc.MinValue; - this.InvokeLeading = leading; - this.InvokeTrailing = trailing; - this.throttlingTimer = new AsyncTimer(this.Execute); - } - - public void Call() - { - this.LastCalled = DateTimeUtc.Now; - - if (this.refreshTimerEnabled == TIMER_DISABLED) - { - this.refreshTimerEnabled = TIMER_ENABLED; - this.LastInvoked = DateTimeUtc.MinValue; - _ = Task.Run(async () => - { - if (this.InvokeLeading) - await this.timerCallback().ConfigureAwait(false); - - this.throttlingTimer.Change(dueTime: this.Interval, period: Timeout.InfiniteTimeSpan); - }); - } - } - - private async Task Execute() - { - var lastCalled = this.LastCalled; - var lastInvoked = this.LastInvoked; - - var timerExpired = lastCalled < lastInvoked; - if (timerExpired) - { - // 前回実行時より後に lastInvoked が更新されていなければタイマーを止める - this.refreshTimerEnabled = TIMER_DISABLED; - - if (this.InvokeTrailing) - await this.timerCallback().ConfigureAwait(false); - } - else - { - var now = DateTimeUtc.Now; - - if ((now - lastInvoked) >= this.MaxWait) - await this.timerCallback().ConfigureAwait(false); - - this.LastInvoked = now; - - // dueTime は Execute が呼ばれる度に再設定する (period は使用しない) - // これにより timerCallback の実行に Interval 以上の時間が掛かっても重複して実行されることはなくなる - lock (this.throttlingTimer) - this.throttlingTimer.Change(dueTime: this.Interval, period: Timeout.InfiniteTimeSpan); - } - } - - public void Dispose() - => this.throttlingTimer.Dispose(); - - // lodash.js の _.throttle, _.debounce 的な処理をしたかったメソッド群 - public static ThrottlingTimer Throttle(Func callback, TimeSpan wait, bool leading = true, bool trailing = true) - => new ThrottlingTimer(callback, wait, maxWait: wait, leading, trailing); - - public static ThrottlingTimer Debounce(Func callback, TimeSpan wait, bool leading = false, bool trailing = true) - => new ThrottlingTimer(callback, wait, maxWait: TimeSpan.MaxValue, leading, trailing); - } -} diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 0a9b99963..8c871614f 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -366,9 +366,9 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ ////////////////////////////////////////////////////////////////////////////////////////////////////////// private readonly TimelineScheduler timelineScheduler = new TimelineScheduler(); - private ThrottlingTimer RefreshThrottlingTimer = null!; - private ThrottlingTimer selectionDebouncer = null!; - private ThrottlingTimer saveConfigDebouncer = null!; + private ThrottleTimer refreshThrottlingTimer = null!; + private DebounceTimer selectionDebouncer = null!; + private DebounceTimer saveConfigDebouncer = null!; private string recommendedStatusFooter = null!; private bool urlMultibyteSplit = false; @@ -1217,9 +1217,9 @@ private void TweenMain_Load(object sender, EventArgs e) this.RefreshTimelineScheduler(); var streamingRefreshInterval = TimeSpan.FromSeconds(SettingManager.Common.UserstreamPeriod); - this.RefreshThrottlingTimer = ThrottlingTimer.Throttle(() => this.InvokeAsync(() => this.RefreshTimeline()), streamingRefreshInterval); - this.selectionDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.UpdateSelectedPost()), TimeSpan.FromMilliseconds(100), leading: true); - this.saveConfigDebouncer = ThrottlingTimer.Debounce(() => this.InvokeAsync(() => this.SaveConfigsAll(ifModified: true)), TimeSpan.FromSeconds(1)); + this.refreshThrottlingTimer = ThrottleTimer.Create(() => this.InvokeAsync(() => this.RefreshTimeline()), streamingRefreshInterval); + this.selectionDebouncer = DebounceTimer.Create(() => this.InvokeAsync(() => this.UpdateSelectedPost()), TimeSpan.FromMilliseconds(100), leading: true); + this.saveConfigDebouncer = DebounceTimer.Create(() => this.InvokeAsync(() => this.SaveConfigsAll(ifModified: true)), TimeSpan.FromSeconds(1)); //更新中アイコンアニメーション間隔 TimerRefreshIcon.Interval = 200; @@ -1379,8 +1379,8 @@ private void TimerInterval_Changed(object sender, IntervalChangedEventArgs e) if (e.UserStream) { var interval = TimeSpan.FromSeconds(SettingManager.Common.UserstreamPeriod); - var newTimer = ThrottlingTimer.Throttle(() => this.InvokeAsync(() => this.RefreshTimeline()), interval); - var oldTimer = Interlocked.Exchange(ref this.RefreshThrottlingTimer, newTimer); + var newTimer = ThrottleTimer.Create(() => this.InvokeAsync(() => this.RefreshTimeline()), interval); + var oldTimer = Interlocked.Exchange(ref this.refreshThrottlingTimer, newTimer); oldTimer.Dispose(); } @@ -1410,7 +1410,7 @@ private void MarkSettingCommonModified() return; this.ModifySettingCommon = true; - this.saveConfigDebouncer.Call(); + _ = this.saveConfigDebouncer.Call(); } private void MarkSettingLocalModified() @@ -1419,7 +1419,7 @@ private void MarkSettingLocalModified() return; this.ModifySettingLocal = true; - this.saveConfigDebouncer.Call(); + _ = this.saveConfigDebouncer.Call(); } internal void MarkSettingAtIdModified() @@ -1428,7 +1428,7 @@ internal void MarkSettingAtIdModified() return; this.ModifySettingAtId = true; - this.saveConfigDebouncer.Call(); + _ = this.saveConfigDebouncer.Call(); } private void RefreshTimeline() @@ -1934,7 +1934,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo } } - private void MyList_SelectedIndexChanged(object sender, EventArgs e) + private async void MyList_SelectedIndexChanged(object sender, EventArgs e) { var listView = this.CurrentListView; if (listView != sender) @@ -1958,7 +1958,7 @@ private void MyList_SelectedIndexChanged(object sender, EventArgs e) ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色) this.ColorizeList(); - this.selectionDebouncer.Call(); + await this.selectionDebouncer.Call(); } private void ChangeCacheStyleRead(bool Read, int Index) @@ -11084,7 +11084,7 @@ private void tw_NewPostFromStream(object sender, EventArgs e) this._statuses.DistributePosts(); - this.RefreshThrottlingTimer.Call(); + _ = this.refreshThrottlingTimer.Call(); } private async void tw_UserStreamStarted(object sender, EventArgs e) From f0b05e07713aa269e6a4bca48d40a95874804322 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 29 Jan 2022 02:13:13 +0900 Subject: [PATCH 041/402] =?UTF-8?q?xUnit=E3=81=AE=E3=83=86=E3=82=B9?= =?UTF-8?q?=E3=83=88=E5=AE=9F=E8=A1=8C=E6=99=82=E3=81=AB=E4=B8=A6=E5=88=97?= =?UTF-8?q?=E5=AE=9F=E8=A1=8C=E3=82=92=E7=84=A1=E5=8A=B9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Properties/AssemblyInfo.cs | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 OpenTween.Tests/Properties/AssemblyInfo.cs diff --git a/OpenTween.Tests/Properties/AssemblyInfo.cs b/OpenTween.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..217120083 --- /dev/null +++ b/OpenTween.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using Xunit; + +[assembly: CollectionBehavior(DisableTestParallelization = true)] From 4962f033c3d6bf1d22f8fa6694d54cfabf57889c Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 29 Jan 2022 05:25:55 +0900 Subject: [PATCH 042/402] =?UTF-8?q?UserStreams=E9=96=A2=E4=BF=82=E3=81=AE?= =?UTF-8?q?=E6=A9=9F=E8=83=BD=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Api/TwitterApiTest.cs | 23 - OpenTween/Api/DataModel/TwitterStreamEvent.cs | 63 -- .../Api/DataModel/TwitterStreamMessage.cs | 61 -- OpenTween/Api/TwitterApi.cs | 16 - OpenTween/Api/TwitterStreamObservable.cs | 12 - OpenTween/AppendSettingDialog.cs | 7 +- OpenTween/EventViewerDialog.Designer.cs | 214 ------- OpenTween/EventViewerDialog.cs | 309 --------- OpenTween/EventViewerDialog.en.resx | 148 ----- OpenTween/EventViewerDialog.resx | 516 --------------- OpenTween/Growl.cs | 10 - OpenTween/Models/TabInformations.cs | 31 - OpenTween/MyCommon.cs | 31 - OpenTween/OpenTween.csproj | 13 - OpenTween/Properties/Resources.Designer.cs | 92 +-- OpenTween/Properties/Resources.en.resx | 30 - OpenTween/Properties/Resources.resx | 30 - OpenTween/Resources/ChangeLog.txt | 1 + .../Setting/Panel/GetPeriodPanel.Designer.cs | 35 -- OpenTween/Setting/Panel/GetPeriodPanel.cs | 33 - .../Setting/Panel/GetPeriodPanel.en.resx | 19 - OpenTween/Setting/Panel/GetPeriodPanel.resx | 176 +----- .../Setting/Panel/NotifyPanel.Designer.cs | 182 ------ OpenTween/Setting/Panel/NotifyPanel.cs | 161 ----- OpenTween/Setting/Panel/NotifyPanel.en.resx | 115 ---- OpenTween/Setting/Panel/NotifyPanel.resx | 477 +------------- OpenTween/Setting/SettingCommon.cs | 11 - OpenTween/Tween.Designer.cs | 63 -- OpenTween/Tween.cs | 415 +----------- OpenTween/Tween.resx | 84 --- OpenTween/Twitter.cs | 595 +----------------- 31 files changed, 61 insertions(+), 3912 deletions(-) delete mode 100644 OpenTween/Api/DataModel/TwitterStreamEvent.cs delete mode 100644 OpenTween/EventViewerDialog.Designer.cs delete mode 100644 OpenTween/EventViewerDialog.cs delete mode 100644 OpenTween/EventViewerDialog.en.resx delete mode 100644 OpenTween/EventViewerDialog.resx diff --git a/OpenTween.Tests/Api/TwitterApiTest.cs b/OpenTween.Tests/Api/TwitterApiTest.cs index 026ec4b74..da1ebc3ba 100644 --- a/OpenTween.Tests/Api/TwitterApiTest.cs +++ b/OpenTween.Tests/Api/TwitterApiTest.cs @@ -1298,28 +1298,5 @@ await twitterApi.MediaMetadataCreate(mediaId: 12345L, altText: "hogehoge") mock.VerifyAll(); } - - [Fact] - public async Task UserStreams_Test() - { - var mock = new Mock(); - mock.Setup(x => - x.GetStreamingStreamAsync( - new Uri("https://userstream.twitter.com/1.1/user.json", UriKind.Absolute), - new Dictionary { - { "replies", "all" }, - { "track", "OpenTween" }, - }) - ) - .ReturnsAsync(new MemoryStream()); - - using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); - twitterApi.apiConnection = mock.Object; - - var observable = twitterApi.UserStreams(replies: "all", track: "OpenTween"); - await observable.ForEachAsync(x => { }); - - mock.VerifyAll(); - } } } diff --git a/OpenTween/Api/DataModel/TwitterStreamEvent.cs b/OpenTween/Api/DataModel/TwitterStreamEvent.cs deleted file mode 100644 index e2aa6a209..000000000 --- a/OpenTween/Api/DataModel/TwitterStreamEvent.cs +++ /dev/null @@ -1,63 +0,0 @@ -// OpenTween - Client of Twitter -// Copyright (c) 2014 kim_upsilon (@kim_upsilon) -// All rights reserved. -// -// This file is part of OpenTween. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program. If not, see , or write to -// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -// Boston, MA 02110-1301, USA. - -#nullable enable annotations - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -namespace OpenTween.Api.DataModel -{ - [DataContract] - public class TwitterStreamEvent - { - [DataMember(Name = "target")] - public TwitterUser Target { get; set; } - - [DataMember(Name = "source")] - public TwitterUser Source { get; set; } - - [DataMember(Name = "event")] - public string Event { get; set; } - - [DataMember(Name = "created_at")] - public string CreatedAt { get; set; } - - /// - public static TwitterStreamEvent ParseJson(string json) - => MyCommon.CreateDataFromJson(json); - } - - [DataContract] - public class TwitterStreamEvent : TwitterStreamEvent - { - [DataMember(Name = "target_object")] - public T TargetObject { get; set; } - - /// - public static new TwitterStreamEvent ParseJson(string json) - => MyCommon.CreateDataFromJson>(json); - } -} diff --git a/OpenTween/Api/DataModel/TwitterStreamMessage.cs b/OpenTween/Api/DataModel/TwitterStreamMessage.cs index 1bf42b12a..f2b46a95a 100644 --- a/OpenTween/Api/DataModel/TwitterStreamMessage.cs +++ b/OpenTween/Api/DataModel/TwitterStreamMessage.cs @@ -40,67 +40,6 @@ public static StreamMessageStatus ParseJson(string json) => new StreamMessageStatus(TwitterStatusCompat.ParseJson(json)); } - public class StreamMessageEvent : ITwitterStreamMessage - { - public TwitterStreamEvent Event { get; } - public string Json { get; } - - public StreamMessageEvent(TwitterStreamEvent eventData, string json) - { - this.Event = eventData; - this.Json = json; - } - - public TwitterStreamEvent ParseTargetObjectAs() - => TwitterStreamEvent.ParseJson(this.Json); - - public static StreamMessageEvent ParseJson(string json) - => new StreamMessageEvent(TwitterStreamEvent.ParseJson(json), json); - } - - [DataContract] - public class StreamMessageDirectMessage : ITwitterStreamMessage - { - [DataMember(Name = "direct_message")] - public TwitterDirectMessage DirectMessage { get; set; } - - public static StreamMessageDirectMessage ParseJson(string json) - => MyCommon.CreateDataFromJson(json); - } - - [DataContract] - public class StreamMessageDelete : ITwitterStreamMessage - { - [DataContract] - public class DeletedId - { - [DataMember(Name = "id")] - public long Id { get; set; } - } - - [DataMember(Name = "direct_message", IsRequired = false)] - public DeletedId? DirectMessage { get; set; } - - [DataMember(Name = "status", IsRequired = false)] - public DeletedId? Status { get; set; } - - public static StreamMessageDelete ParseJson(string json) - => MyCommon.CreateDataFromJson(json); - } - - [DataContract] - public class StreamMessageScrubGeo : ITwitterStreamMessage - { - [DataMember(Name = "user_id")] - public long UserId { get; set; } - - [DataMember(Name = "up_to_status_id")] - public long UpToStatusId { get; set; } - - public static StreamMessageScrubGeo ParseJson(string json) - => MyCommon.CreateDataFromJson(json); - } - public class StreamMessageKeepAlive : ITwitterStreamMessage { } diff --git a/OpenTween/Api/TwitterApi.cs b/OpenTween/Api/TwitterApi.cs index 593c3d65b..928de6f6a 100644 --- a/OpenTween/Api/TwitterApi.cs +++ b/OpenTween/Api/TwitterApi.cs @@ -779,22 +779,6 @@ public Task MediaMetadataCreate(long mediaId, string altText) return this.Connection.PostJsonAsync(endpoint, json); } - public TwitterStreamObservable UserStreams(string? replies = null, string? track = null) - { - var endpoint = new Uri("https://userstream.twitter.com/1.1/user.json"); - var param = new Dictionary(); - - if (!MyCommon.IsNullOrEmpty(replies)) - param["replies"] = replies; - if (!MyCommon.IsNullOrEmpty(track)) - param["track"] = track; - - Task openStream() - => this.Connection.GetStreamingStreamAsync(endpoint, param); - - return new TwitterStreamObservable(openStream); - } - public OAuthEchoHandler CreateOAuthEchoHandler(Uri authServiceProvider, Uri? realm = null) => ((TwitterApiConnection)this.Connection).CreateOAuthEchoHandler(authServiceProvider, realm); diff --git a/OpenTween/Api/TwitterStreamObservable.cs b/OpenTween/Api/TwitterStreamObservable.cs index d9c83fb50..815f06d26 100644 --- a/OpenTween/Api/TwitterStreamObservable.cs +++ b/OpenTween/Api/TwitterStreamObservable.cs @@ -97,18 +97,6 @@ public static ITwitterStreamMessage ParseLine(string line) if (xElm.Element("text") != null) return StreamMessageStatus.ParseJson(line); - if (xElm.Element("delete") != null) - return StreamMessageDelete.ParseJson(line); - - if (xElm.Element("event") != null) - return StreamMessageEvent.ParseJson(line); - - if (xElm.Element("direct_message") != null) - return StreamMessageDirectMessage.ParseJson(line); - - if (xElm.Element("scrub_geo") != null) - return StreamMessageScrubGeo.ParseJson(line); - return new StreamMessageUnknown(line); } catch (XmlException) diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index b7dc66b47..3cd416d5b 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -299,7 +299,7 @@ public void ApplyNetworkSettings() } private void CheckPostAndGet_CheckedChanged(object sender, EventArgs e) - => this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked && !tw.UserStreamActive; + => this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked; private void Setting_Shown(object sender, EventArgs e) { @@ -310,8 +310,7 @@ private void Setting_Shown(object sender, EventArgs e) } while (!this.IsHandleCreated); this.TopMost = this.PreviewPanel.CheckAlwaysTop.Checked; - this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked && !tw.UserStreamActive; - this.GetPeriodPanel.LabelUserStreamActive.Visible = tw.UserStreamActive; + this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked; } private void OpenUrl(string url) @@ -358,7 +357,6 @@ private void GetPeriodPanel_IntervalChanged(object sender, IntervalChangedEventA public class IntervalChangedEventArgs : EventArgs { - public bool UserStream; public bool Timeline; public bool Reply; public bool DirectMessage; @@ -368,7 +366,6 @@ public class IntervalChangedEventArgs : EventArgs public static IntervalChangedEventArgs ResetAll => new IntervalChangedEventArgs { - UserStream = true, Timeline = true, Reply = true, DirectMessage = true, diff --git a/OpenTween/EventViewerDialog.Designer.cs b/OpenTween/EventViewerDialog.Designer.cs deleted file mode 100644 index 75fc26384..000000000 --- a/OpenTween/EventViewerDialog.Designer.cs +++ /dev/null @@ -1,214 +0,0 @@ -namespace OpenTween -{ - partial class EventViewerDialog - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(EventViewerDialog)); - this.SaveLogButton = new System.Windows.Forms.Button(); - this.CheckBoxFilter = new System.Windows.Forms.CheckBox(); - this.TabPageAll = new System.Windows.Forms.TabPage(); - this.EventList = new System.Windows.Forms.ListView(); - this.ColumnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.ColumnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.ColumnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.ColumnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); - this.CheckRegex = new System.Windows.Forms.CheckBox(); - this.TextBoxKeyword = new System.Windows.Forms.TextBox(); - this.StatusLabelCount = new System.Windows.Forms.ToolStripStatusLabel(); - this.OK_Button = new System.Windows.Forms.Button(); - this.StatusStrip1 = new System.Windows.Forms.StatusStrip(); - this.TabEventType = new System.Windows.Forms.TabControl(); - this.ButtonRefresh = new System.Windows.Forms.Button(); - this.CheckExcludeMyEvent = new System.Windows.Forms.CheckBox(); - this.SaveFileDialog1 = new System.Windows.Forms.SaveFileDialog(); - this.TabPageAll.SuspendLayout(); - this.StatusStrip1.SuspendLayout(); - this.TabEventType.SuspendLayout(); - this.SuspendLayout(); - // - // SaveLogButton - // - resources.ApplyResources(this.SaveLogButton, "SaveLogButton"); - this.SaveLogButton.Name = "SaveLogButton"; - this.SaveLogButton.UseVisualStyleBackColor = true; - this.SaveLogButton.Click += new System.EventHandler(this.SaveLogButton_Click); - // - // CheckBoxFilter - // - resources.ApplyResources(this.CheckBoxFilter, "CheckBoxFilter"); - this.CheckBoxFilter.Name = "CheckBoxFilter"; - this.CheckBoxFilter.UseVisualStyleBackColor = true; - this.CheckBoxFilter.CheckedChanged += new System.EventHandler(this.TabEventType_SelectedIndexChanged); - // - // TabPageAll - // - this.TabPageAll.AccessibleRole = System.Windows.Forms.AccessibleRole.PageTab; - this.TabPageAll.Controls.Add(this.EventList); - resources.ApplyResources(this.TabPageAll, "TabPageAll"); - this.TabPageAll.Name = "TabPageAll"; - this.TabPageAll.Tag = "All"; - this.TabPageAll.UseVisualStyleBackColor = true; - // - // EventList - // - this.EventList.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.ColumnHeader1, - this.ColumnHeader2, - this.ColumnHeader3, - this.ColumnHeader4}); - resources.ApplyResources(this.EventList, "EventList"); - this.EventList.FullRowSelect = true; - this.EventList.Name = "EventList"; - this.EventList.ShowItemToolTips = true; - this.EventList.UseCompatibleStateImageBehavior = false; - this.EventList.View = System.Windows.Forms.View.Details; - this.EventList.VirtualMode = true; - this.EventList.CacheVirtualItems += new System.Windows.Forms.CacheVirtualItemsEventHandler(this.EventList_CacheVirtualItems); - this.EventList.RetrieveVirtualItem += new System.Windows.Forms.RetrieveVirtualItemEventHandler(this.EventList_RetrieveVirtualItem); - this.EventList.DoubleClick += new System.EventHandler(this.EventList_DoubleClick); - this.EventList.KeyDown += new System.Windows.Forms.KeyEventHandler(this.EventList_KeyDown); - // - // ColumnHeader1 - // - resources.ApplyResources(this.ColumnHeader1, "ColumnHeader1"); - // - // ColumnHeader2 - // - resources.ApplyResources(this.ColumnHeader2, "ColumnHeader2"); - // - // ColumnHeader3 - // - resources.ApplyResources(this.ColumnHeader3, "ColumnHeader3"); - // - // ColumnHeader4 - // - resources.ApplyResources(this.ColumnHeader4, "ColumnHeader4"); - // - // CheckRegex - // - resources.ApplyResources(this.CheckRegex, "CheckRegex"); - this.CheckRegex.Name = "CheckRegex"; - this.CheckRegex.UseVisualStyleBackColor = true; - // - // TextBoxKeyword - // - resources.ApplyResources(this.TextBoxKeyword, "TextBoxKeyword"); - this.TextBoxKeyword.Name = "TextBoxKeyword"; - this.TextBoxKeyword.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.TextBoxKeyword_KeyPress); - // - // StatusLabelCount - // - this.StatusLabelCount.Name = "StatusLabelCount"; - resources.ApplyResources(this.StatusLabelCount, "StatusLabelCount"); - // - // OK_Button - // - resources.ApplyResources(this.OK_Button, "OK_Button"); - this.OK_Button.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.OK_Button.Name = "OK_Button"; - this.OK_Button.Click += new System.EventHandler(this.OK_Button_Click); - // - // StatusStrip1 - // - this.StatusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.StatusLabelCount}); - resources.ApplyResources(this.StatusStrip1, "StatusStrip1"); - this.StatusStrip1.Name = "StatusStrip1"; - // - // TabEventType - // - resources.ApplyResources(this.TabEventType, "TabEventType"); - this.TabEventType.Controls.Add(this.TabPageAll); - this.TabEventType.Name = "TabEventType"; - this.TabEventType.SelectedIndex = 0; - this.TabEventType.SelectedIndexChanged += new System.EventHandler(this.TabEventType_SelectedIndexChanged); - this.TabEventType.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(this.TabEventType_Selecting); - // - // ButtonRefresh - // - resources.ApplyResources(this.ButtonRefresh, "ButtonRefresh"); - this.ButtonRefresh.Name = "ButtonRefresh"; - this.ButtonRefresh.UseVisualStyleBackColor = true; - this.ButtonRefresh.Click += new System.EventHandler(this.ButtonRefresh_Click); - // - // CheckExcludeMyEvent - // - resources.ApplyResources(this.CheckExcludeMyEvent, "CheckExcludeMyEvent"); - this.CheckExcludeMyEvent.Name = "CheckExcludeMyEvent"; - this.CheckExcludeMyEvent.UseVisualStyleBackColor = true; - this.CheckExcludeMyEvent.CheckedChanged += new System.EventHandler(this.CheckExcludeMyEvent_CheckedChanged); - // - // EventViewerDialog - // - resources.ApplyResources(this, "$this"); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.CancelButton = this.OK_Button; - this.Controls.Add(this.SaveLogButton); - this.Controls.Add(this.CheckBoxFilter); - this.Controls.Add(this.CheckRegex); - this.Controls.Add(this.TextBoxKeyword); - this.Controls.Add(this.OK_Button); - this.Controls.Add(this.StatusStrip1); - this.Controls.Add(this.TabEventType); - this.Controls.Add(this.ButtonRefresh); - this.Controls.Add(this.CheckExcludeMyEvent); - this.DoubleBuffered = true; - this.Name = "EventViewerDialog"; - this.ShowIcon = false; - this.ShowInTaskbar = false; - this.Shown += new System.EventHandler(this.EventViewerDialog_Shown); - this.TabPageAll.ResumeLayout(false); - this.StatusStrip1.ResumeLayout(false); - this.StatusStrip1.PerformLayout(); - this.TabEventType.ResumeLayout(false); - this.ResumeLayout(false); - this.PerformLayout(); - - } - - #endregion - - internal System.Windows.Forms.Button SaveLogButton; - internal System.Windows.Forms.CheckBox CheckBoxFilter; - internal System.Windows.Forms.TabPage TabPageAll; - internal System.Windows.Forms.ListView EventList; - internal System.Windows.Forms.ColumnHeader ColumnHeader1; - internal System.Windows.Forms.ColumnHeader ColumnHeader2; - internal System.Windows.Forms.ColumnHeader ColumnHeader3; - internal System.Windows.Forms.ColumnHeader ColumnHeader4; - internal System.Windows.Forms.CheckBox CheckRegex; - internal System.Windows.Forms.TextBox TextBoxKeyword; - internal System.Windows.Forms.ToolStripStatusLabel StatusLabelCount; - internal System.Windows.Forms.Button OK_Button; - internal System.Windows.Forms.StatusStrip StatusStrip1; - internal System.Windows.Forms.TabControl TabEventType; - internal System.Windows.Forms.Button ButtonRefresh; - internal System.Windows.Forms.CheckBox CheckExcludeMyEvent; - internal System.Windows.Forms.SaveFileDialog SaveFileDialog1; - } -} \ No newline at end of file diff --git a/OpenTween/EventViewerDialog.cs b/OpenTween/EventViewerDialog.cs deleted file mode 100644 index bf572581a..000000000 --- a/OpenTween/EventViewerDialog.cs +++ /dev/null @@ -1,309 +0,0 @@ -// OpenTween - Client of Twitter -// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) -// (c) 2008-2011 Moz (@syo68k) -// (c) 2008-2011 takeshik (@takeshik) -// (c) 2010-2011 anis774 (@anis774) -// (c) 2010-2011 fantasticswallow (@f_swallow) -// (c) 2011-2012 kim_upsilon (@kim_upsilon) -// All rights reserved. -// -// This file is part of OpenTween. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License -// for more details. -// -// You should have received a copy of the GNU General public License along -// with this program. If not, see , or write to -// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -// Boston, MA 02110-1301, USA. - -#nullable enable - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Diagnostics.CodeAnalysis; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Windows.Forms; -using System.Text.RegularExpressions; -using System.IO; -using System.Globalization; -using OpenTween.Setting; -using System.Threading.Tasks; - -namespace OpenTween -{ - public partial class EventViewerDialog : OTBaseForm - { - public List EventSource { get; set; } = new List(); - - private Twitter.FormattedEvent[] _filterdEventSource = Array.Empty(); - - private ListViewItem[]? _ItemCache = null; - private int _itemCacheIndex; - - private TabPage _curTab = null!; - - public EventViewerDialog() - { - InitializeComponent(); - - // メイリオフォント指定時にタブの最小幅が広くなる問題の対策 - this.TabEventType.HandleCreated += (s, e) => NativeMethods.SetMinTabWidth((TabControl)s, 40); - } - - protected override void ScaleControl(SizeF factor, BoundsSpecified specified) - { - base.ScaleControl(factor, specified); - ScaleChildControl(this.EventList, factor); - } - - private void OK_Button_Click(object sender, EventArgs e) - { - this.DialogResult = DialogResult.OK; - this.Close(); - } - - private void Cancel_Button_Click(object sender, EventArgs e) - { - this.DialogResult = DialogResult.Cancel; - this.Close(); - } - - private ListViewItem CreateListViewItem(Twitter.FormattedEvent source) - { - string[] s = { source.CreatedAt.ToLocalTimeString(), source.Event.ToUpper(CultureInfo.CurrentCulture), source.Username, source.Target }; - return new ListViewItem(s); - } - - private void EventViewerDialog_Shown(object sender, EventArgs e) - { - // タブ初期化 - foreach (var tabPage in CreateTabsFromUserStreamsEvent()) - { - TabEventType.TabPages.Add(tabPage); - } - - EventList.BeginUpdate(); - _curTab = TabEventType.SelectedTab; - CreateFilterdEventSource(); - EventList.EndUpdate(); - this.TopMost = SettingManager.Common.AlwaysTop; - } - - private async void EventList_DoubleClick(object sender, EventArgs e) - => await this.OpenEventStatusOrUser(); - - private async void EventList_KeyDown(object sender, KeyEventArgs e) - { - if (e.KeyData == Keys.Enter) - await this.OpenEventStatusOrUser(); - } - - private async Task OpenEventStatusOrUser() - { - if (this.EventList.SelectedIndices.Count == 0) - return; - - var tweenMain = (TweenMain)this.Owner; - var selectedEvent = this._filterdEventSource[this.EventList.SelectedIndices[0]]; - if (selectedEvent != null) - { - if (selectedEvent.Id != 0) - await tweenMain.OpenRelatedTab(selectedEvent.Id); - else - await tweenMain.OpenUriAsync(new Uri("https://twitter.com/" + selectedEvent.Username)); - } - } - - private MyCommon.EVENTTYPE ParseEventTypeFromTag() - => (MyCommon.EVENTTYPE)Enum.Parse(typeof(MyCommon.EVENTTYPE), _curTab.Tag.ToString()); - - private bool IsFilterMatch(Twitter.FormattedEvent x) - { - if (!CheckBoxFilter.Checked || MyCommon.IsNullOrEmpty(TextBoxKeyword.Text)) - { - return true; - } - else - { - if (CheckRegex.Checked) - { - try - { - var rx = new Regex(TextBoxKeyword.Text); - return rx.Match(x.Username).Success || rx.Match(x.Target).Success; - } - catch (Exception ex) - { - MessageBox.Show(Properties.Resources.ButtonOK_ClickText3 + ex.Message, "", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - return false; - } - } - else - { - return x.Username.Contains(TextBoxKeyword.Text) || x.Target.Contains(TextBoxKeyword.Text); - } - } - } - - private void CreateFilterdEventSource() - { - if (EventSource != null && EventSource.Count > 0) - { - _filterdEventSource = EventSource.FindAll((x) => !(CheckExcludeMyEvent.Checked && x.IsMe) && - (x.Eventtype & ParseEventTypeFromTag()) != 0 && - IsFilterMatch(x)).ToArray(); - _ItemCache = null; - EventList.VirtualListSize = _filterdEventSource.Count(); - StatusLabelCount.Text = string.Format("{0} / {1}", _filterdEventSource.Count(), EventSource.Count()); - } - else - { - StatusLabelCount.Text = "0 / 0"; - } - } - - private void CheckExcludeMyEvent_CheckedChanged(object sender, EventArgs e) - => this.CreateFilterdEventSource(); - - private void ButtonRefresh_Click(object sender, EventArgs e) - => this.CreateFilterdEventSource(); - - private void TabEventType_SelectedIndexChanged(object sender, EventArgs e) - => this.CreateFilterdEventSource(); - - private void TabEventType_Selecting(object sender, TabControlCancelEventArgs e) - { - _curTab = e.TabPage; - if (!e.TabPage.Controls.Contains(EventList)) - { - e.TabPage.Controls.Add(EventList); - } - } - - private void TextBoxKeyword_KeyPress(object sender, KeyPressEventArgs e) - { - if (e.KeyChar == (char)Keys.Enter) - { - CreateFilterdEventSource(); - e.Handled = true; - } - } - - private void EventList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) - { - if (_ItemCache != null && e.ItemIndex >= _itemCacheIndex && e.ItemIndex < _itemCacheIndex + _ItemCache.Length) - { - //キャッシュヒット - e.Item = _ItemCache[e.ItemIndex - _itemCacheIndex]; - } - else - { - //キャッシュミス - e.Item = CreateListViewItem(_filterdEventSource[e.ItemIndex]); - } - } - - private void EventList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) - => this.CreateCache(e.StartIndex, e.EndIndex); - - private void CreateCache(int StartIndex, int EndIndex) - { - //キャッシュ要求(要求範囲±30を作成) - StartIndex -= 30; - if (StartIndex < 0) StartIndex = 0; - EndIndex += 30; - if (EndIndex > _filterdEventSource.Count() - 1) - { - EndIndex = _filterdEventSource.Count() - 1; - } - _ItemCache = new ListViewItem[] { }; - Array.Resize(ref _ItemCache, EndIndex - StartIndex + 1); - _itemCacheIndex = StartIndex; - for (var i = 0; i < _ItemCache.Length; i++) - { - _ItemCache[i] = CreateListViewItem(_filterdEventSource[StartIndex + i]); - } - } - - private void SaveLogButton_Click(object sender, EventArgs e) - { - var rslt = MessageBox.Show(string.Format(Properties.Resources.SaveLogMenuItem_ClickText5, Environment.NewLine), - Properties.Resources.SaveLogMenuItem_ClickText2, - MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question); - switch (rslt) - { - case DialogResult.Yes: - SaveFileDialog1.FileName = $"{ApplicationSettings.AssemblyName}Events{_curTab.Tag}{DateTimeUtc.Now.ToLocalTime():yyMMdd-HHmmss}.tsv"; - break; - case DialogResult.No: - SaveFileDialog1.FileName = $"{ApplicationSettings.AssemblyName}Events{DateTimeUtc.Now.ToLocalTime():yyMMdd-HHmmss}.tsv"; - break; - default: - return; - } - - SaveFileDialog1.InitialDirectory = Application.StartupPath; - SaveFileDialog1.Filter = Properties.Resources.SaveLogMenuItem_ClickText3; - SaveFileDialog1.FilterIndex = 0; - SaveFileDialog1.Title = Properties.Resources.SaveLogMenuItem_ClickText4; - SaveFileDialog1.RestoreDirectory = true; - - if (SaveFileDialog1.ShowDialog() == DialogResult.OK) - { - if (!SaveFileDialog1.ValidateNames) return; - using var sw = new StreamWriter(SaveFileDialog1.FileName, false, Encoding.UTF8); - - switch (rslt) - { - case DialogResult.Yes: - SaveEventLog(_filterdEventSource.ToList(), sw); - break; - case DialogResult.No: - SaveEventLog(EventSource, sw); - break; - default: - break; - } - } - this.TopMost = SettingManager.Common.AlwaysTop; - } - - private void SaveEventLog(List source, StreamWriter sw) - { - foreach (var _event in source) - { - sw.WriteLine(_event.Eventtype + "\t" + - "\"" + _event.CreatedAt.ToLocalTimeString() + "\"\t" + - _event.Event + "\t" + - _event.Username + "\t" + - _event.Target + "\t" + - _event.Id); - } - } - - [SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")] - private static IEnumerable CreateTabsFromUserStreamsEvent() - { - return Enum.GetNames(typeof(MyCommon.EVENTTYPE)) - .Where(e => e != "None" && e != "All") - .Select(e => new TabPage(e) - { - Tag = e, - UseVisualStyleBackColor = true, - AccessibleRole = AccessibleRole.PageTab, - }); - } - } -} diff --git a/OpenTween/EventViewerDialog.en.resx b/OpenTween/EventViewerDialog.en.resx deleted file mode 100644 index 119f3d1ea..000000000 --- a/OpenTween/EventViewerDialog.en.resx +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 126, 16 - - - Exclude own events - - - Refresh - - - All - - - 56, 16 - - - Regex - - - 105, 16 - - - Keyword search - - - Save... - - \ No newline at end of file diff --git a/OpenTween/EventViewerDialog.resx b/OpenTween/EventViewerDialog.resx deleted file mode 100644 index 3d438744c..000000000 --- a/OpenTween/EventViewerDialog.resx +++ /dev/null @@ -1,516 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - - Bottom, Right - - - 599, 239 - - - 126, 22 - - - 5 - - - ファイル保存 - - - SaveLogButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - Bottom, Left - - - True - - - 12, 277 - - - 124, 16 - - - 2 - - - キーワードで絞り込む - - - CheckBoxFilter - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - EventList - - - System.Windows.Forms.ListView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TabPageAll - - - 0 - - - 4, 4 - - - 3, 3, 3, 3 - - - 706, 193 - - - 0 - - - 全て - - - TabPageAll - - - System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TabEventType - - - 0 - - - Fill - - - 3, 3 - - - 700, 187 - - - 0 - - - Datetime - - - 86 - - - Type - - - 90 - - - Username - - - 106 - - - Target - - - 360 - - - Bottom, Left - - - True - - - 12, 299 - - - 72, 16 - - - 4 - - - 正規表現 - - - CheckRegex - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Bottom, Left - - - 142, 275 - - - 231, 19 - - - 3 - - - TextBoxKeyword - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - 95, 17 - - - StatusLabelCount - - - Bottom, Right - - - 659, 298 - - - 67, 21 - - - 7 - - - OK - - - OK_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - 24, 10 - - - 0, 340 - - - 738, 22 - - - 7 - - - StatusStrip1 - - - StatusStrip1 - - - System.Windows.Forms.StatusStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - Bottom - - - Top, Bottom, Left, Right - - - 12, 12 - - - 714, 218 - - - 0 - - - TabEventType - - - System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - Bottom, Right - - - 600, 269 - - - 126, 21 - - - 6 - - - 最新の情報に更新 - - - ButtonRefresh - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - Bottom, Left - - - True - - - 12, 255 - - - 197, 16 - - - 1 - - - 自分が発生させたイベントを除外する - - - CheckExcludeMyEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - 150, 10 - - - True - - - 39 - - - 96, 96 - - - 738, 362 - - - Manual - - - Events - - - ColumnHeader1 - - - System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ColumnHeader2 - - - System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ColumnHeader3 - - - System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ColumnHeader4 - - - System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - StatusLabelCount - - - System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SaveFileDialog1 - - - System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EventViewerDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file diff --git a/OpenTween/Growl.cs b/OpenTween/Growl.cs index 70efc4d2f..f989ec912 100644 --- a/OpenTween/Growl.cs +++ b/OpenTween/Growl.cs @@ -49,7 +49,6 @@ public class GrowlHelper private object? _growlNTreply; private object? _growlNTdm; private object? _growlNTnew; - private object? _growlNTusevent; private object? _growlApp; private object? _targetConnector; @@ -78,7 +77,6 @@ public enum NotifyType Reply = 0, DirectMessage = 1, Notify = 2, - UserStreamEvent = 3, } public GrowlHelper(string appName) @@ -155,9 +153,6 @@ public bool RegisterGrowl() _growlNTnew = _t.InvokeMember(null, BindingFlags.CreateInstance, null, null, new object[] { "NOTIFY", "新着通知" }, CultureInfo.InvariantCulture); - _growlNTusevent = _t.InvokeMember(null, - BindingFlags.CreateInstance, null, null, new object[] { "USERSTREAM_EVENT", "UserStream Event" }, CultureInfo.InvariantCulture); - var encryptType = _connector.GetType("Growl.Connector.Cryptography+SymmetricAlgorithmType").InvokeMember( "PlainText", BindingFlags.GetField, null, null, null, CultureInfo.InvariantCulture); @@ -228,7 +223,6 @@ public bool RegisterGrowl() _growlNTreply, _growlNTdm, _growlNTnew, - _growlNTusevent, }; mi.Invoke(_targetConnector, new object[] { _growlApp, arglist.ToArray(_t) }); @@ -263,7 +257,6 @@ public void Notify(NotifyType notificationType, string id, string title, string NotifyType.Reply => "REPLY", NotifyType.DirectMessage => "DIRECT_MESSAGE", NotifyType.Notify => "NOTIFY", - NotifyType.UserStreamEvent => "USERSTREAM_EVENT", _ => "", }; @@ -360,9 +353,6 @@ private void GrowlCallbackHandler(object response, object callbackData, object s case "NOTIFY": nt = NotifyType.Notify; break; - case "USERSTREAM_EVENT": - nt = NotifyType.UserStreamEvent; - break; default: return; } diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index 1dc4f1fc2..d3cce54ea 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -279,37 +279,6 @@ public SortOrder ToggleSortOrder(ComparerMode sortMode) public PostClass? RetweetSource(long Id) => this.Posts.TryGetValue(Id, out var status) ? status : null; - public void ScrubGeoReserve(long id, long upToStatusId) - { - lock (LockObj) - this.ScrubGeo(id, upToStatusId); - } - - private void ScrubGeo(long userId, long upToStatusId) - { - lock (LockObj) - { - var userPosts = from post in this.Posts.Values - where post.UserId == userId && post.UserId <= upToStatusId - select post; - - foreach (var p in userPosts) - { - p.PostGeo = null; - } - - var userPosts2 = from tb in this.GetTabsInnerStorageType() - from post in tb.Posts.Values - where post.UserId == userId && post.UserId <= upToStatusId - select post; - - foreach (var p in userPosts2) - { - p.PostGeo = null; - } - } - } - public void RemovePostFromAllTabs(long statusId, bool setIsDeleted) { foreach (var tab in this.Tabs) diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 82d8ff41f..bc06bd177 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -149,7 +149,6 @@ public enum WORKERTYPE PublicSearch, //公式検索 List, //Lists Related, //関連発言 - UserStream, //UserStream UserTimeline, //UserTimeline BlockIds, //Blocking/ids Configuration, //Twitter Configuration読み込み @@ -189,36 +188,6 @@ public enum REPLY_ICONSTATE BlinkIcon, } - [Flags] - public enum EVENTTYPE - { - None = 0, - Favorite = 1, - Unfavorite = 2, - Follow = 4, - ListMemberAdded = 8, - ListMemberRemoved = 16, - Block = 32, - Unblock = 64, - UserUpdate = 128, - Deleted = 256, - ListCreated = 512, - ListUpdated = 1024, - Unfollow = 2048, - ListUserSubscribed = 4096, - ListUserUnsubscribed = 8192, - ListDestroyed = 16384, - Mute = 32768, - Unmute = 65536, - QuotedTweet = 131072, - Retweet = 262144, - - All = (None | Favorite | Unfavorite | Follow | ListMemberAdded | ListMemberRemoved | - Block | Unblock | UserUpdate | Deleted | ListCreated | ListUpdated | Unfollow | - ListUserSubscribed | ListUserUnsubscribed | ListDestroyed | - Mute | Unmute | QuotedTweet | Retweet), - } - public static _Assembly EntryAssembly { get; internal set; } public static string FileVersion { get; internal set; } diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index b4fbf607d..a7ec6b0b3 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -85,7 +85,6 @@ - @@ -141,12 +140,6 @@ EncryptApiKeyDialog.cs - - Form - - - EventViewerDialog.cs - Form @@ -481,12 +474,6 @@ EncryptApiKeyDialog.cs - - EventViewerDialog.cs - - - EventViewerDialog.cs - FilterDialog.cs diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 4d26930f7..298e6f129 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace OpenTween.Properties { // または Visual Studio のようなツールを使用して自動生成されました。 // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { @@ -141,51 +141,6 @@ internal static string AddTabMenuItem_ClickText2 { } } - /// - /// REST API上限 : に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo1 { - get { - return ResourceManager.GetString("ApiInfo1", resourceCulture); - } - } - - /// - /// 画像投稿API残数: に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo10 { - get { - return ResourceManager.GetString("ApiInfo10", resourceCulture); - } - } - - /// - /// 画像投稿APIリセット日時: に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo11 { - get { - return ResourceManager.GetString("ApiInfo11", resourceCulture); - } - } - - /// - /// REST API残数 : に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo2 { - get { - return ResourceManager.GetString("ApiInfo2", resourceCulture); - } - } - - /// - /// REST API残数リセット日時 : に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo3 { - get { - return ResourceManager.GetString("ApiInfo3", resourceCulture); - } - } - /// /// API情報 に類似しているローカライズされた文字列を検索します。 /// @@ -213,42 +168,6 @@ internal static string ApiInfo6 { } } - /// - /// UserStream接続 : に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo7 { - get { - return ResourceManager.GetString("ApiInfo7", resourceCulture); - } - } - - /// - /// APIアクセス権限: に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo8 { - get { - return ResourceManager.GetString("ApiInfo8", resourceCulture); - } - } - - /// - /// 画像投稿API上限: に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo9 { - get { - return ResourceManager.GetString("ApiInfo9", resourceCulture); - } - } - - /// - /// (画像投稿後に取得/更新されます) に類似しているローカライズされた文字列を検索します。 - /// - internal static string ApiInfo91 { - get { - return ResourceManager.GetString("ApiInfo91", resourceCulture); - } - } - /// /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 /// @@ -3212,15 +3131,6 @@ internal static string UserInfoButtonEdit_ClickText2 { } } - /// - /// 反映間隔には数値(0~60)を指定してください。 に類似しているローカライズされた文字列を検索します。 - /// - internal static string UserstreamPeriod_ValidatingText1 { - get { - return ResourceManager.GetString("UserstreamPeriod_ValidatingText1", resourceCulture); - } - } - /// /// タイトル: に類似しているローカライズされた文字列を検索します。 /// diff --git a/OpenTween/Properties/Resources.en.resx b/OpenTween/Properties/Resources.en.resx index 0dc5af684..3a90bbc42 100644 --- a/OpenTween/Properties/Resources.en.resx +++ b/OpenTween/Properties/Resources.en.resx @@ -588,15 +588,6 @@ CaseSensitive/ - - Upper bound : - - - Remain count : - - - Reset time : - API Information @@ -907,9 +898,6 @@ Do you want to upload the {1} selected media file(s)? Confirm Unfollow - - Refresh interval must be number 0 to 60 - UserTimeline @@ -937,24 +925,6 @@ Do you want to upload the {1} selected media file(s)? Thank you for registration! - - MediaRateLimit : - - - MediaRateLimit(RestTime) : - - - UserStreams : - - - Access Level : - - - MediaRateLimit(Remaining) : - - - (unknown) - Delete selected rules? ({0} nums) diff --git a/OpenTween/Properties/Resources.resx b/OpenTween/Properties/Resources.resx index 979575686..b06eb0b12 100644 --- a/OpenTween/Properties/Resources.resx +++ b/OpenTween/Properties/Resources.resx @@ -640,15 +640,6 @@ 大小区別/ - - REST API上限 : - - - REST API残数 : - - - REST API残数リセット日時 : - API情報 @@ -992,18 +983,12 @@ フォロー解除確認 - - 反映間隔には数値(0~60)を指定してください。 - UserTimeline ja - - UserStream接続 : - 無効 @@ -1058,21 +1043,6 @@ 登録ありがとうございます。 - - 画像投稿API残数: - - - 画像投稿APIリセット日時: - - - APIアクセス権限: - - - 画像投稿API上限: - - - (画像投稿後に取得/更新されます) - 削除(&D) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 02a9533df..a212275f1 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -4,6 +4,7 @@ * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 * CHG: Instagramのサムネイルを表示するURLのパターンを追加 * CHG: YouTubeのサムネイルを表示するURLのパターンを追加 (thx @Hawklaver!) + * CHG: UserStreams関係の機能を削除 * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) diff --git a/OpenTween/Setting/Panel/GetPeriodPanel.Designer.cs b/OpenTween/Setting/Panel/GetPeriodPanel.Designer.cs index ac7dbf9e4..41fd4ba04 100644 --- a/OpenTween/Setting/Panel/GetPeriodPanel.Designer.cs +++ b/OpenTween/Setting/Panel/GetPeriodPanel.Designer.cs @@ -29,9 +29,6 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(GetPeriodPanel)); - this.UserstreamPeriod = new System.Windows.Forms.TextBox(); - this.Label46 = new System.Windows.Forms.Label(); - this.LabelUserStreamActive = new System.Windows.Forms.Label(); this.Label21 = new System.Windows.Forms.Label(); this.UserTimelinePeriod = new System.Windows.Forms.TextBox(); this.TimelinePeriod = new System.Windows.Forms.TextBox(); @@ -46,25 +43,8 @@ private void InitializeComponent() this.CheckPostAndGet = new System.Windows.Forms.CheckBox(); this.Label5 = new System.Windows.Forms.Label(); this.DMPeriod = new System.Windows.Forms.TextBox(); - this.StartupUserstreamCheck = new System.Windows.Forms.CheckBox(); this.SuspendLayout(); // - // UserstreamPeriod - // - resources.ApplyResources(this.UserstreamPeriod, "UserstreamPeriod"); - this.UserstreamPeriod.Name = "UserstreamPeriod"; - this.UserstreamPeriod.Validating += new System.ComponentModel.CancelEventHandler(this.UserstreamPeriod_Validating); - // - // Label46 - // - resources.ApplyResources(this.Label46, "Label46"); - this.Label46.Name = "Label46"; - // - // LabelUserStreamActive - // - resources.ApplyResources(this.LabelUserStreamActive, "LabelUserStreamActive"); - this.LabelUserStreamActive.Name = "LabelUserStreamActive"; - // // Label21 // resources.ApplyResources(this.Label21, "Label21"); @@ -141,19 +121,10 @@ private void InitializeComponent() this.DMPeriod.Name = "DMPeriod"; this.DMPeriod.Validating += new System.ComponentModel.CancelEventHandler(this.DMPeriod_Validating); // - // StartupUserstreamCheck - // - resources.ApplyResources(this.StartupUserstreamCheck, "StartupUserstreamCheck"); - this.StartupUserstreamCheck.Name = "StartupUserstreamCheck"; - this.StartupUserstreamCheck.UseVisualStyleBackColor = true; - // // GetPeriodPanel // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.Controls.Add(this.UserstreamPeriod); - this.Controls.Add(this.Label46); - this.Controls.Add(this.LabelUserStreamActive); this.Controls.Add(this.Label21); this.Controls.Add(this.UserTimelinePeriod); this.Controls.Add(this.TimelinePeriod); @@ -168,7 +139,6 @@ private void InitializeComponent() this.Controls.Add(this.CheckPostAndGet); this.Controls.Add(this.Label5); this.Controls.Add(this.DMPeriod); - this.Controls.Add(this.StartupUserstreamCheck); this.Name = "GetPeriodPanel"; this.ResumeLayout(false); this.PerformLayout(); @@ -176,10 +146,6 @@ private void InitializeComponent() } #endregion - - internal System.Windows.Forms.TextBox UserstreamPeriod; - internal System.Windows.Forms.Label Label46; - internal System.Windows.Forms.Label LabelUserStreamActive; internal System.Windows.Forms.Label Label21; internal System.Windows.Forms.TextBox UserTimelinePeriod; internal System.Windows.Forms.TextBox TimelinePeriod; @@ -194,6 +160,5 @@ private void InitializeComponent() internal System.Windows.Forms.CheckBox CheckPostAndGet; internal System.Windows.Forms.Label Label5; internal System.Windows.Forms.TextBox DMPeriod; - internal System.Windows.Forms.CheckBox StartupUserstreamCheck; } } diff --git a/OpenTween/Setting/Panel/GetPeriodPanel.cs b/OpenTween/Setting/Panel/GetPeriodPanel.cs index fb0d496ee..fdeadc904 100644 --- a/OpenTween/Setting/Panel/GetPeriodPanel.cs +++ b/OpenTween/Setting/Panel/GetPeriodPanel.cs @@ -46,9 +46,7 @@ public GetPeriodPanel() public void LoadConfig(SettingCommon settingCommon) { - this.StartupUserstreamCheck.Checked = settingCommon.UserstreamStartup; this.CheckPostAndGet.Checked = settingCommon.PostAndGet; - this.UserstreamPeriod.Text = settingCommon.UserstreamPeriod.ToString(); this.TimelinePeriod.Text = settingCommon.TimelinePeriod.ToString(); this.ReplyPeriod.Text = settingCommon.ReplyPeriod.ToString(); this.DMPeriod.Text = settingCommon.DMPeriod.ToString(); @@ -59,20 +57,11 @@ public void LoadConfig(SettingCommon settingCommon) public void SaveConfig(SettingCommon settingCommon) { - settingCommon.UserstreamStartup = this.StartupUserstreamCheck.Checked; settingCommon.PostAndGet = this.CheckPostAndGet.Checked; var arg = new IntervalChangedEventArgs(); var isIntervalChanged = false; - var userstreamPeriod = int.Parse(this.UserstreamPeriod.Text); - if (settingCommon.UserstreamPeriod != userstreamPeriod) - { - settingCommon.UserstreamPeriod = userstreamPeriod; - arg.UserStream = true; - isIntervalChanged = true; - } - var timelinePeriod = int.Parse(this.TimelinePeriod.Text); if (settingCommon.TimelinePeriod != timelinePeriod) { @@ -125,28 +114,6 @@ public void SaveConfig(SettingCommon settingCommon) this.IntervalChanged?.Invoke(this, arg); } - private void UserstreamPeriod_Validating(object sender, CancelEventArgs e) - { - int prd; - try - { - prd = int.Parse(UserstreamPeriod.Text); - } - catch (Exception) - { - MessageBox.Show(Properties.Resources.UserstreamPeriod_ValidatingText1); - e.Cancel = true; - return; - } - - if (prd < 0 || prd > 60) - { - MessageBox.Show(Properties.Resources.UserstreamPeriod_ValidatingText1); - e.Cancel = true; - return; - } - } - private void TimelinePeriod_Validating(object sender, CancelEventArgs e) { int prd; diff --git a/OpenTween/Setting/Panel/GetPeriodPanel.en.resx b/OpenTween/Setting/Panel/GetPeriodPanel.en.resx index 2ef73ea1f..ebc92a02e 100644 --- a/OpenTween/Setting/Panel/GetPeriodPanel.en.resx +++ b/OpenTween/Setting/Panel/GetPeriodPanel.en.resx @@ -118,19 +118,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 191, 12 - - - User Streams Refresh Interval (sec) - - - 395, 24 - - - UserStream is enable. -Periodic fetching, Timeline/Mentions/DM, and Post&Fetch function is disable. - UserTimeline Interval (sec) @@ -176,10 +163,4 @@ Periodic fetching, Timeline/Mentions/DM, and Post&Fetch function is disable. DM Fetching Interval (sec.) - - 149, 16 - - - Auto connect at starting - \ No newline at end of file diff --git a/OpenTween/Setting/Panel/GetPeriodPanel.resx b/OpenTween/Setting/Panel/GetPeriodPanel.resx index 7eaf894ed..dae4ec5e5 100644 --- a/OpenTween/Setting/Panel/GetPeriodPanel.resx +++ b/OpenTween/Setting/Panel/GetPeriodPanel.resx @@ -117,103 +117,17 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Disable - - - - 259, 23 - - - 65, 19 - - - 21 - - - UserstreamPeriod - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 23, 26 - - - 137, 12 - - - 20 - - - UserStream反映間隔(秒) - - - Label46 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - NoControl - - - 23, 303 - - - 348, 36 - - - 37 - - - UserStreamが有効です。 -タイムライン/Mentions/DMの定期更新、投稿時取得は停止しています。 -これらはUserStreamによりリアルタイム更新されます。 - - - LabelUserStreamActive - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - True + NoControl + - 23, 217 + 23, 182 144, 12 @@ -234,13 +148,13 @@ $this - 3 + 0 Disable - 259, 214 + 259, 179 65, 19 @@ -258,13 +172,13 @@ $this - 4 + 1 Disable - 259, 52 + 259, 17 65, 19 @@ -282,7 +196,7 @@ $this - 5 + 2 True @@ -291,7 +205,7 @@ NoControl - 23, 55 + 23, 20 130, 12 @@ -312,7 +226,7 @@ $this - 6 + 3 True @@ -342,7 +256,7 @@ $this - 7 + 4 True @@ -351,7 +265,7 @@ NoControl - 23, 188 + 23, 153 102, 12 @@ -372,13 +286,13 @@ $this - 8 + 5 Disable - 259, 185 + 259, 150 65, 19 @@ -396,7 +310,7 @@ $this - 9 + 6 True @@ -405,7 +319,7 @@ NoControl - 23, 159 + 23, 124 137, 12 @@ -426,13 +340,13 @@ $this - 10 + 7 Disable - 259, 156 + 259, 121 65, 19 @@ -450,7 +364,7 @@ $this - 11 + 8 True @@ -459,7 +373,7 @@ NoControl - 23, 101 + 23, 66 123, 12 @@ -480,13 +394,13 @@ $this - 12 + 9 Disable - 259, 98 + 259, 63 65, 19 @@ -504,7 +418,7 @@ $this - 13 + 10 True @@ -513,7 +427,7 @@ NoControl - 45, 73 + 45, 38 84, 16 @@ -534,7 +448,7 @@ $this - 14 + 11 True @@ -543,7 +457,7 @@ NoControl - 23, 130 + 23, 95 94, 12 @@ -564,13 +478,13 @@ $this - 15 + 12 Disable - 259, 127 + 259, 92 65, 19 @@ -588,37 +502,7 @@ $this - 16 - - - True - - - NoControl - - - 330, 25 - - - 117, 16 - - - 22 - - - 起動時に自動接続 - - - StartupUserstreamCheck - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 17 + 13 True @@ -630,6 +514,6 @@ GetPeriodPanel - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null \ No newline at end of file diff --git a/OpenTween/Setting/Panel/NotifyPanel.Designer.cs b/OpenTween/Setting/Panel/NotifyPanel.Designer.cs index 55d7d3826..d356c68ae 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.Designer.cs +++ b/OpenTween/Setting/Panel/NotifyPanel.Designer.cs @@ -29,199 +29,17 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NotifyPanel)); - this.IsRemoveSameFavEventCheckBox = new System.Windows.Forms.CheckBox(); - this.CheckUserUpdateEvent = new System.Windows.Forms.CheckBox(); - this.Label35 = new System.Windows.Forms.Label(); - this.ComboBoxEventNotifySound = new System.Windows.Forms.ComboBox(); - this.CheckFavEventUnread = new System.Windows.Forms.CheckBox(); - this.CheckListCreatedEvent = new System.Windows.Forms.CheckBox(); - this.CheckBlockEvent = new System.Windows.Forms.CheckBox(); - this.CheckForceEventNotify = new System.Windows.Forms.CheckBox(); - this.CheckListMemberRemovedEvent = new System.Windows.Forms.CheckBox(); - this.CheckListMemberAddedEvent = new System.Windows.Forms.CheckBox(); - this.CheckFollowEvent = new System.Windows.Forms.CheckBox(); - this.CheckUnfavoritesEvent = new System.Windows.Forms.CheckBox(); - this.CheckFavoritesEvent = new System.Windows.Forms.CheckBox(); - this.CheckEventNotify = new System.Windows.Forms.CheckBox(); - this.CheckQuotedTweetEvent = new System.Windows.Forms.CheckBox(); - this.CheckRetweetEvent = new System.Windows.Forms.CheckBox(); this.SuspendLayout(); // - // IsRemoveSameFavEventCheckBox - // - resources.ApplyResources(this.IsRemoveSameFavEventCheckBox, "IsRemoveSameFavEventCheckBox"); - this.IsRemoveSameFavEventCheckBox.Name = "IsRemoveSameFavEventCheckBox"; - this.IsRemoveSameFavEventCheckBox.UseVisualStyleBackColor = true; - // - // CheckUserUpdateEvent - // - resources.ApplyResources(this.CheckUserUpdateEvent, "CheckUserUpdateEvent"); - this.CheckUserUpdateEvent.Checked = true; - this.CheckUserUpdateEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckUserUpdateEvent.Name = "CheckUserUpdateEvent"; - this.CheckUserUpdateEvent.ThreeState = true; - this.CheckUserUpdateEvent.UseVisualStyleBackColor = true; - // - // Label35 - // - resources.ApplyResources(this.Label35, "Label35"); - this.Label35.Name = "Label35"; - // - // ComboBoxEventNotifySound - // - this.ComboBoxEventNotifySound.FormattingEnabled = true; - resources.ApplyResources(this.ComboBoxEventNotifySound, "ComboBoxEventNotifySound"); - this.ComboBoxEventNotifySound.Name = "ComboBoxEventNotifySound"; - // - // CheckFavEventUnread - // - resources.ApplyResources(this.CheckFavEventUnread, "CheckFavEventUnread"); - this.CheckFavEventUnread.Checked = true; - this.CheckFavEventUnread.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckFavEventUnread.Name = "CheckFavEventUnread"; - this.CheckFavEventUnread.UseVisualStyleBackColor = true; - // - // CheckListCreatedEvent - // - resources.ApplyResources(this.CheckListCreatedEvent, "CheckListCreatedEvent"); - this.CheckListCreatedEvent.Checked = true; - this.CheckListCreatedEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckListCreatedEvent.Name = "CheckListCreatedEvent"; - this.CheckListCreatedEvent.ThreeState = true; - this.CheckListCreatedEvent.UseVisualStyleBackColor = true; - // - // CheckBlockEvent - // - resources.ApplyResources(this.CheckBlockEvent, "CheckBlockEvent"); - this.CheckBlockEvent.Checked = true; - this.CheckBlockEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckBlockEvent.Name = "CheckBlockEvent"; - this.CheckBlockEvent.ThreeState = true; - this.CheckBlockEvent.UseVisualStyleBackColor = true; - // - // CheckForceEventNotify - // - resources.ApplyResources(this.CheckForceEventNotify, "CheckForceEventNotify"); - this.CheckForceEventNotify.Checked = true; - this.CheckForceEventNotify.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckForceEventNotify.Name = "CheckForceEventNotify"; - this.CheckForceEventNotify.UseVisualStyleBackColor = true; - // - // CheckListMemberRemovedEvent - // - resources.ApplyResources(this.CheckListMemberRemovedEvent, "CheckListMemberRemovedEvent"); - this.CheckListMemberRemovedEvent.Checked = true; - this.CheckListMemberRemovedEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckListMemberRemovedEvent.Name = "CheckListMemberRemovedEvent"; - this.CheckListMemberRemovedEvent.ThreeState = true; - this.CheckListMemberRemovedEvent.UseVisualStyleBackColor = true; - // - // CheckListMemberAddedEvent - // - resources.ApplyResources(this.CheckListMemberAddedEvent, "CheckListMemberAddedEvent"); - this.CheckListMemberAddedEvent.Checked = true; - this.CheckListMemberAddedEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckListMemberAddedEvent.Name = "CheckListMemberAddedEvent"; - this.CheckListMemberAddedEvent.ThreeState = true; - this.CheckListMemberAddedEvent.UseVisualStyleBackColor = true; - // - // CheckFollowEvent - // - resources.ApplyResources(this.CheckFollowEvent, "CheckFollowEvent"); - this.CheckFollowEvent.Checked = true; - this.CheckFollowEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckFollowEvent.Name = "CheckFollowEvent"; - this.CheckFollowEvent.ThreeState = true; - this.CheckFollowEvent.UseVisualStyleBackColor = true; - // - // CheckUnfavoritesEvent - // - resources.ApplyResources(this.CheckUnfavoritesEvent, "CheckUnfavoritesEvent"); - this.CheckUnfavoritesEvent.Checked = true; - this.CheckUnfavoritesEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckUnfavoritesEvent.Name = "CheckUnfavoritesEvent"; - this.CheckUnfavoritesEvent.ThreeState = true; - this.CheckUnfavoritesEvent.UseVisualStyleBackColor = true; - // - // CheckFavoritesEvent - // - resources.ApplyResources(this.CheckFavoritesEvent, "CheckFavoritesEvent"); - this.CheckFavoritesEvent.Checked = true; - this.CheckFavoritesEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckFavoritesEvent.Name = "CheckFavoritesEvent"; - this.CheckFavoritesEvent.ThreeState = true; - this.CheckFavoritesEvent.UseVisualStyleBackColor = true; - // - // CheckEventNotify - // - resources.ApplyResources(this.CheckEventNotify, "CheckEventNotify"); - this.CheckEventNotify.Checked = true; - this.CheckEventNotify.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckEventNotify.Name = "CheckEventNotify"; - this.CheckEventNotify.UseVisualStyleBackColor = true; - this.CheckEventNotify.CheckedChanged += new System.EventHandler(this.CheckEventNotify_CheckedChanged); - // - // CheckQuotedTweetEvent - // - resources.ApplyResources(this.CheckQuotedTweetEvent, "CheckQuotedTweetEvent"); - this.CheckQuotedTweetEvent.Checked = true; - this.CheckQuotedTweetEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckQuotedTweetEvent.Name = "CheckQuotedTweetEvent"; - this.CheckQuotedTweetEvent.ThreeState = true; - this.CheckQuotedTweetEvent.UseVisualStyleBackColor = true; - // - // CheckRetweetEvent - // - resources.ApplyResources(this.CheckRetweetEvent, "CheckRetweetEvent"); - this.CheckRetweetEvent.Checked = true; - this.CheckRetweetEvent.CheckState = System.Windows.Forms.CheckState.Checked; - this.CheckRetweetEvent.Name = "CheckRetweetEvent"; - this.CheckRetweetEvent.ThreeState = true; - this.CheckRetweetEvent.UseVisualStyleBackColor = true; - // // NotifyPanel // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.Controls.Add(this.IsRemoveSameFavEventCheckBox); - this.Controls.Add(this.CheckUserUpdateEvent); - this.Controls.Add(this.Label35); - this.Controls.Add(this.ComboBoxEventNotifySound); - this.Controls.Add(this.CheckFavEventUnread); - this.Controls.Add(this.CheckListCreatedEvent); - this.Controls.Add(this.CheckBlockEvent); - this.Controls.Add(this.CheckForceEventNotify); - this.Controls.Add(this.CheckListMemberRemovedEvent); - this.Controls.Add(this.CheckListMemberAddedEvent); - this.Controls.Add(this.CheckFollowEvent); - this.Controls.Add(this.CheckUnfavoritesEvent); - this.Controls.Add(this.CheckFavoritesEvent); - this.Controls.Add(this.CheckEventNotify); - this.Controls.Add(this.CheckRetweetEvent); - this.Controls.Add(this.CheckQuotedTweetEvent); this.Name = "NotifyPanel"; this.ResumeLayout(false); - this.PerformLayout(); } #endregion - - internal System.Windows.Forms.CheckBox IsRemoveSameFavEventCheckBox; - internal System.Windows.Forms.CheckBox CheckUserUpdateEvent; - internal System.Windows.Forms.Label Label35; - internal System.Windows.Forms.ComboBox ComboBoxEventNotifySound; - internal System.Windows.Forms.CheckBox CheckFavEventUnread; - internal System.Windows.Forms.CheckBox CheckListCreatedEvent; - internal System.Windows.Forms.CheckBox CheckBlockEvent; - internal System.Windows.Forms.CheckBox CheckForceEventNotify; - internal System.Windows.Forms.CheckBox CheckListMemberRemovedEvent; - internal System.Windows.Forms.CheckBox CheckListMemberAddedEvent; - internal System.Windows.Forms.CheckBox CheckFollowEvent; - internal System.Windows.Forms.CheckBox CheckUnfavoritesEvent; - internal System.Windows.Forms.CheckBox CheckFavoritesEvent; - internal System.Windows.Forms.CheckBox CheckEventNotify; - internal System.Windows.Forms.CheckBox CheckQuotedTweetEvent; - internal System.Windows.Forms.CheckBox CheckRetweetEvent; } } diff --git a/OpenTween/Setting/Panel/NotifyPanel.cs b/OpenTween/Setting/Panel/NotifyPanel.cs index 5a7c16859..7e3ac68c3 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.cs +++ b/OpenTween/Setting/Panel/NotifyPanel.cs @@ -28,13 +28,8 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Data; using System.Linq; using System.Text; -using System.Windows.Forms; -using System.IO; namespace OpenTween.Setting.Panel { @@ -45,166 +40,10 @@ public NotifyPanel() public void LoadConfig(SettingCommon settingCommon) { - this.ApplyEventNotifyFlag(settingCommon.EventNotifyEnabled, settingCommon.EventNotifyFlag, settingCommon.IsMyEventNotifyFlag); - this.CheckForceEventNotify.Checked = settingCommon.ForceEventNotify; - this.CheckFavEventUnread.Checked = settingCommon.FavEventUnread; - - this.SoundFileListup(); - - var soundFile = settingCommon.EventSoundFile ?? ""; - var soundFileIdx = this.ComboBoxEventNotifySound.Items.IndexOf(soundFile); - if (soundFileIdx != -1) - this.ComboBoxEventNotifySound.SelectedIndex = soundFileIdx; - - this.IsRemoveSameFavEventCheckBox.Checked = settingCommon.IsRemoveSameEvent; } public void SaveConfig(SettingCommon settingCommon) { - settingCommon.EventNotifyEnabled = this.CheckEventNotify.Checked; - this.GetEventNotifyFlag(ref settingCommon.EventNotifyFlag, ref settingCommon.IsMyEventNotifyFlag); - settingCommon.ForceEventNotify = this.CheckForceEventNotify.Checked; - settingCommon.FavEventUnread = this.CheckFavEventUnread.Checked; - settingCommon.EventSoundFile = (string)this.ComboBoxEventNotifySound.SelectedItem; - settingCommon.IsRemoveSameEvent = this.IsRemoveSameFavEventCheckBox.Checked; - } - - private void SoundFileListup() - { - this.ComboBoxEventNotifySound.Items.Clear(); - this.ComboBoxEventNotifySound.Items.Add(""); - var oDir = new DirectoryInfo(Application.StartupPath + Path.DirectorySeparatorChar); - if (Directory.Exists(Path.Combine(Application.StartupPath, "Sounds"))) - { - oDir = oDir.GetDirectories("Sounds")[0]; - } - foreach (var oFile in oDir.GetFiles("*.wav")) - { - this.ComboBoxEventNotifySound.Items.Add(oFile.Name); - } - } - - private class EventCheckboxTblElement - { - public CheckBox CheckBox = null!; - public MyCommon.EVENTTYPE Type; - } - - private EventCheckboxTblElement[] GetEventCheckboxTable() - { - return new[] - { - new EventCheckboxTblElement - { - CheckBox = this.CheckFavoritesEvent, - Type = MyCommon.EVENTTYPE.Favorite, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckUnfavoritesEvent, - Type = MyCommon.EVENTTYPE.Unfavorite, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckFollowEvent, - Type = MyCommon.EVENTTYPE.Follow, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckListMemberAddedEvent, - Type = MyCommon.EVENTTYPE.ListMemberAdded, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckListMemberRemovedEvent, - Type = MyCommon.EVENTTYPE.ListMemberRemoved, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckBlockEvent, - Type = MyCommon.EVENTTYPE.Block, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckUserUpdateEvent, - Type = MyCommon.EVENTTYPE.UserUpdate, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckListCreatedEvent, - Type = MyCommon.EVENTTYPE.ListCreated, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckQuotedTweetEvent, - Type = MyCommon.EVENTTYPE.QuotedTweet, - }, - new EventCheckboxTblElement - { - CheckBox = this.CheckRetweetEvent, - Type = MyCommon.EVENTTYPE.Retweet, - }, - }; - } - - private void GetEventNotifyFlag(ref MyCommon.EVENTTYPE eventnotifyflag, ref MyCommon.EVENTTYPE isMyeventnotifyflag) - { - var evt = MyCommon.EVENTTYPE.None; - var myevt = MyCommon.EVENTTYPE.None; - - foreach (var tbl in GetEventCheckboxTable()) - { - switch (tbl.CheckBox.CheckState) - { - case CheckState.Checked: - evt |= tbl.Type; - myevt |= tbl.Type; - break; - case CheckState.Indeterminate: - evt |= tbl.Type; - break; - case CheckState.Unchecked: - break; - } - } - eventnotifyflag = evt; - isMyeventnotifyflag = myevt; - } - - private void ApplyEventNotifyFlag(bool rootEnabled, MyCommon.EVENTTYPE eventnotifyflag, MyCommon.EVENTTYPE isMyeventnotifyflag) - { - var evt = eventnotifyflag; - var myevt = isMyeventnotifyflag; - - this.CheckEventNotify.Checked = rootEnabled; - - foreach (var tbl in GetEventCheckboxTable()) - { - if ((evt & tbl.Type) != 0) - { - if ((myevt & tbl.Type) != 0) - { - tbl.CheckBox.CheckState = CheckState.Checked; - } - else - { - tbl.CheckBox.CheckState = CheckState.Indeterminate; - } - } - else - { - tbl.CheckBox.CheckState = CheckState.Unchecked; - } - tbl.CheckBox.Enabled = rootEnabled; - } - } - - private void CheckEventNotify_CheckedChanged(object sender, EventArgs e) - { - foreach (var tbl in this.GetEventCheckboxTable()) - { - tbl.CheckBox.Enabled = this.CheckEventNotify.Checked; - } } } } diff --git a/OpenTween/Setting/Panel/NotifyPanel.en.resx b/OpenTween/Setting/Panel/NotifyPanel.en.resx index 123741d41..1af7de150 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.en.resx +++ b/OpenTween/Setting/Panel/NotifyPanel.en.resx @@ -117,119 +117,4 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 254, 16 - - - Ignore duplicated Favorite/Unfavorite events - - - 45, 195 - - - 85, 16 - - - Bio updated - - - 132, 12 - - - Play sound notify events - - - 190, 16 - - - Mark favorited tweets as unread - - - 45, 220 - - - 91, 16 - - - Lists created - - - 45, 170 - - - 68, 16 - - - Blocking - - - 234, 16 - - - Notify Events even if disable alert popup - - - 45, 145 - - - 147, 16 - - - Removed from the Lists - - - 45, 120 - - - 119, 16 - - - Added to the Lists - - - 45, 95 - - - 69, 16 - - - Followed - - - 45, 70 - - - 94, 16 - - - Fav Removed - - - 45, 48 - - - 79, 16 - - - Fav Added - - - 189, 16 - - - Notify Events(Only UserStream) - - - 60, 16 - - - Quotes - - - 72, 16 - - - Retweets - \ No newline at end of file diff --git a/OpenTween/Setting/Panel/NotifyPanel.resx b/OpenTween/Setting/Panel/NotifyPanel.resx index 8efc29341..0510b4380 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.resx +++ b/OpenTween/Setting/Panel/NotifyPanel.resx @@ -117,483 +117,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - - NoControl - - - - 23, 298 - - - 260, 16 - - - 28 - - - 重複するFav追加、Fav削除のイベントは無視する - - - IsRemoveSameFavEventCheckBox - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 40, 198 - - - 189, 16 - - - 22 - - - ユーザーのプロフィールが更新された - - - CheckUserUpdateEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - NoControl - - - 23, 326 - - - 176, 12 - - - 26 - - - イベント通知の際に再生するサウンド - - - Label35 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - 286, 323 - - - 188, 20 - - - 27 - - - ComboBoxEventNotifySound - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 273 - - - 271, 16 - - - 25 - - - Favoritesイベント受信の際に書き込みを未読に戻す - - - CheckFavEventUnread - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 40, 223 - - - 134, 16 - - - 23 - - - Listsの作成に成功した - - - CheckListCreatedEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 40, 173 - - - 211, 16 - - - 21 - - - 他のユーザーに対するブロックが成功した - - - CheckBlockEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - NoControl - - - 23, 248 - - - 213, 16 - - - 24 - - - 新着通知が無効でもイベントを通知する - - - CheckForceEventNotify - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - True - - - NoControl - - - 40, 148 - - - 119, 16 - - - 20 - - - Listsから削除された - - - CheckListMemberRemovedEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - True - - - NoControl - - - 40, 123 - - - 110, 16 - - - 19 - - - Listsに追加された - - - CheckListMemberAddedEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - True - - - NoControl - - - 40, 98 - - - 87, 16 - - - 18 - - - フォローされた - - - CheckFollowEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - True - - - NoControl - - - 40, 73 - - - 192, 16 - - - 17 - - - Fav削除した、またはFav削除された - - - CheckUnfavoritesEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - True - - - NoControl - - - 40, 48 - - - 192, 16 - - - 16 - - - Fav追加した、またはFav追加された - - - CheckFavoritesEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 12 - - - True - - - NoControl - - - 23, 23 - - - 376, 16 - - - 15 - - - 次のイベントを受信したときにバルーンで通知する(UserStream有効時のみ) - - - CheckEventNotify - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 13 - - - True - - - NoControl - - - 275, 48 - - - 199, 16 - - - 29 - - - ツイートを引用した、または引用された - - - CheckQuotedTweetEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 15 - - - True - - - NoControl - - - 275, 73 - - - 184, 16 - - - 30 - - - 公式RTした、または公式RTされた - - - CheckRetweetEvent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 14 - True + 96, 96 @@ -601,6 +128,6 @@ NotifyPanel - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null \ No newline at end of file diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index e5d8dfa75..ac8793169 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -116,13 +116,7 @@ private string Decrypt(string password) public bool ListLock = false; public MyCommon.IconSizes IconSize = MyCommon.IconSizes.Icon16; public bool NewAllPop = true; - public bool EventNotifyEnabled = true; - public MyCommon.EVENTTYPE EventNotifyFlag = MyCommon.EVENTTYPE.All; - public MyCommon.EVENTTYPE IsMyEventNotifyFlag = MyCommon.EVENTTYPE.All; - public bool ForceEventNotify = false; - public bool FavEventUnread = true; public string TranslateLanguage = Properties.Resources.TranslateDefaultLanguage; - public string EventSoundFile = ""; /// /// サウンド再生(タブ別設定より優先) @@ -216,10 +210,6 @@ private string Decrypt(string password) public int FirstCountApi = 100; public int SearchCountApi = 100; public int FavoritesCountApi = 40; - public string TrackWord = ""; - public bool AllAtReply = false; - public bool UserstreamStartup = true; - public int UserstreamPeriod = 0; public int UserTimelineCountApi = 20; public int UserTimelinePeriod = 600; public bool OpenUserTimeline = true; @@ -237,7 +227,6 @@ private string Decrypt(string password) public MapProvider MapThumbnailProvider = MapProvider.OpenStreetMap; public bool IsListsIncludeRts = false; public bool TabMouseLock = false; - public bool IsRemoveSameEvent = false; public bool IsUseNotifyGrowl = false; public bool ForceIPv4 = false; public bool ErrorReportAnonymous = true; diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index 99cd1ad52..f9ce2098d 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -179,13 +179,6 @@ private void InitializeComponent() this.ToolStripSeparator34 = new System.Windows.Forms.ToolStripSeparator(); this.RtCountMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ListManageToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.MenuItemUserStream = new System.Windows.Forms.ToolStripMenuItem(); - this.StopToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripSeparator40 = new System.Windows.Forms.ToolStripSeparator(); - this.TrackToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.AllrepliesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ToolStripSeparator42 = new System.Windows.Forms.ToolStripSeparator(); - this.EventViewerMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.MenuItemHelp = new System.Windows.Forms.ToolStripMenuItem(); this.MatomeMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShortcutKeyListMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -715,7 +708,6 @@ private void InitializeComponent() this.MenuItemOperate, this.MenuItemTab, this.MenuItemCommand, - this.MenuItemUserStream, this.MenuItemHelp}); this.MenuStrip1.Name = "MenuStrip1"; this.MenuStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional; @@ -1523,54 +1515,6 @@ private void InitializeComponent() resources.ApplyResources(this.ListManageToolStripMenuItem, "ListManageToolStripMenuItem"); this.ListManageToolStripMenuItem.Click += new System.EventHandler(this.ListManageToolStripMenuItem_Click); // - // MenuItemUserStream - // - this.MenuItemUserStream.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.StopToolStripMenuItem, - this.ToolStripSeparator40, - this.TrackToolStripMenuItem, - this.AllrepliesToolStripMenuItem, - this.ToolStripSeparator42, - this.EventViewerMenuItem}); - resources.ApplyResources(this.MenuItemUserStream, "MenuItemUserStream"); - this.MenuItemUserStream.Name = "MenuItemUserStream"; - // - // StopToolStripMenuItem - // - this.StopToolStripMenuItem.Name = "StopToolStripMenuItem"; - resources.ApplyResources(this.StopToolStripMenuItem, "StopToolStripMenuItem"); - this.StopToolStripMenuItem.Click += new System.EventHandler(this.StopToolStripMenuItem_Click); - // - // ToolStripSeparator40 - // - this.ToolStripSeparator40.Name = "ToolStripSeparator40"; - resources.ApplyResources(this.ToolStripSeparator40, "ToolStripSeparator40"); - // - // TrackToolStripMenuItem - // - this.TrackToolStripMenuItem.CheckOnClick = true; - this.TrackToolStripMenuItem.Name = "TrackToolStripMenuItem"; - resources.ApplyResources(this.TrackToolStripMenuItem, "TrackToolStripMenuItem"); - this.TrackToolStripMenuItem.Click += new System.EventHandler(this.TrackToolStripMenuItem_Click); - // - // AllrepliesToolStripMenuItem - // - this.AllrepliesToolStripMenuItem.CheckOnClick = true; - this.AllrepliesToolStripMenuItem.Name = "AllrepliesToolStripMenuItem"; - resources.ApplyResources(this.AllrepliesToolStripMenuItem, "AllrepliesToolStripMenuItem"); - this.AllrepliesToolStripMenuItem.Click += new System.EventHandler(this.AllrepliesToolStripMenuItem_Click); - // - // ToolStripSeparator42 - // - this.ToolStripSeparator42.Name = "ToolStripSeparator42"; - resources.ApplyResources(this.ToolStripSeparator42, "ToolStripSeparator42"); - // - // EventViewerMenuItem - // - this.EventViewerMenuItem.Name = "EventViewerMenuItem"; - resources.ApplyResources(this.EventViewerMenuItem, "EventViewerMenuItem"); - this.EventViewerMenuItem.Click += new System.EventHandler(this.EventViewerMenuItem_Click); - // // MenuItemHelp // this.MenuItemHelp.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -2306,13 +2250,6 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator34; internal System.Windows.Forms.ToolStripMenuItem RtCountMenuItem; internal System.Windows.Forms.ToolStripMenuItem ListManageToolStripMenuItem; - internal System.Windows.Forms.ToolStripMenuItem MenuItemUserStream; - internal System.Windows.Forms.ToolStripMenuItem StopToolStripMenuItem; - internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator40; - internal System.Windows.Forms.ToolStripMenuItem TrackToolStripMenuItem; - internal System.Windows.Forms.ToolStripMenuItem AllrepliesToolStripMenuItem; - internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator42; - internal System.Windows.Forms.ToolStripMenuItem EventViewerMenuItem; internal System.Windows.Forms.ToolStripMenuItem MenuItemHelp; internal System.Windows.Forms.ToolStripMenuItem MatomeMenuItem; internal System.Windows.Forms.ToolStripMenuItem ShortcutKeyListMenuItem; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 8c871614f..a53e55d0f 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -160,7 +160,6 @@ public partial class TweenMain : OTBaseForm public AtIdSupplement HashSupl = null!; public HashtagManage HashMgr = null!; - private EventViewerDialog evtDialog = null!; //表示フォント、色、アイコン @@ -366,7 +365,6 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ ////////////////////////////////////////////////////////////////////////////////////////////////////////// private readonly TimelineScheduler timelineScheduler = new TimelineScheduler(); - private ThrottleTimer refreshThrottlingTimer = null!; private DebounceTimer selectionDebouncer = null!; private DebounceTimer saveConfigDebouncer = null!; @@ -508,7 +506,6 @@ protected override void Dispose(bool disposing) this.thumbnailTokenSource?.Dispose(); - this.tw.Dispose(); this.twitterApi.Dispose(); this._hookGlobalHotkey.Dispose(); } @@ -910,10 +907,6 @@ private void TweenMain_Load(object sender, EventArgs e) TwitterApiConnection.RestApiHost = SettingManager.Common.TwitterApiHost; tw.RestrictFavCheck = SettingManager.Common.RestrictFavCheck; tw.ReadOwnPost = SettingManager.Common.ReadOwnPost; - tw.TrackWord = SettingManager.Common.TrackWord; - TrackToolStripMenuItem.Checked = !MyCommon.IsNullOrEmpty(tw.TrackWord); - tw.AllAtReply = SettingManager.Common.AllAtReply; - AllrepliesToolStripMenuItem.Checked = tw.AllAtReply; ShortUrl.Instance.DisableExpanding = !SettingManager.Common.TinyUrlResolve; ShortUrl.Instance.BitlyAccessToken = SettingManager.Common.BitlyAccessToken; ShortUrl.Instance.BitlyId = SettingManager.Common.BilyUser; @@ -1216,8 +1209,6 @@ private void TweenMain_Load(object sender, EventArgs e) })); this.RefreshTimelineScheduler(); - var streamingRefreshInterval = TimeSpan.FromSeconds(SettingManager.Common.UserstreamPeriod); - this.refreshThrottlingTimer = ThrottleTimer.Create(() => this.InvokeAsync(() => this.RefreshTimeline()), streamingRefreshInterval); this.selectionDebouncer = DebounceTimer.Create(() => this.InvokeAsync(() => this.UpdateSelectedPost()), TimeSpan.FromMilliseconds(100), leading: true); this.saveConfigDebouncer = DebounceTimer.Create(() => this.InvokeAsync(() => this.SaveConfigsAll(ifModified: true)), TimeSpan.FromSeconds(1)); @@ -1376,14 +1367,6 @@ private void LoadConfig() private void TimerInterval_Changed(object sender, IntervalChangedEventArgs e) { - if (e.UserStream) - { - var interval = TimeSpan.FromSeconds(SettingManager.Common.UserstreamPeriod); - var newTimer = ThrottleTimer.Create(() => this.InvokeAsync(() => this.RefreshTimeline()), interval); - var oldTimer = Interlocked.Exchange(ref this.refreshThrottlingTimer, newTimer); - oldTimer.Dispose(); - } - this.RefreshTimelineScheduler(); } @@ -1710,35 +1693,6 @@ private void RestoreListViewSelection(DetailsListView listView, TabModel tab, Li } private bool BalloonRequired() - { - var ev = new Twitter.FormattedEvent - { - Eventtype = MyCommon.EVENTTYPE.None, - }; - - return BalloonRequired(ev); - } - - private bool IsEventNotifyAsEventType(MyCommon.EVENTTYPE type) - { - if (type == MyCommon.EVENTTYPE.None) - return true; - - if (!SettingManager.Common.EventNotifyEnabled) - return false; - - return SettingManager.Common.EventNotifyFlag.HasFlag(type); - } - - private bool IsMyEventNotityAsEventType(Twitter.FormattedEvent ev) - { - if (!ev.IsMe) - return true; - - return SettingManager.Common.IsMyEventNotifyFlag.HasFlag(ev.Eventtype); - } - - private bool BalloonRequired(Twitter.FormattedEvent ev) { if (this._initial) return false; @@ -1748,11 +1702,7 @@ private bool BalloonRequired(Twitter.FormattedEvent ev) // 「新着通知」が無効 if (!this.NewPostPopMenuItem.Checked) - { - // 「新着通知が無効でもイベントを通知する」にも該当しない - if (!SettingManager.Common.ForceEventNotify || ev.Eventtype == MyCommon.EVENTTYPE.None) - return false; - } + return false; // 「画面最小化・アイコン時のみバルーンを表示する」が有効 if (SettingManager.Common.LimitBalloon) @@ -1761,7 +1711,7 @@ private bool BalloonRequired(Twitter.FormattedEvent ev) return false; } - return this.IsEventNotifyAsEventType(ev.Eventtype) && this.IsMyEventNotityAsEventType(ev); + return true; } private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCount, bool newMentions) @@ -2720,19 +2670,16 @@ await Task.Run(async () => this.SetMainWindowTitle(); // TLに反映 - if (!this.tw.UserStreamActive) + if (SettingManager.Common.PostAndGet) + await this.RefreshTabAsync(); + else { - if (SettingManager.Common.PostAndGet) - await this.RefreshTabAsync(); - else + if (post != null) { - if (post != null) - { - this._statuses.AddPost(post); - this._statuses.DistributePosts(); - } - this.RefreshTimeline(); + this._statuses.AddPost(post); + this._statuses.DistributePosts(); } + this.RefreshTimeline(); } } @@ -2799,20 +2746,16 @@ await Task.Run(async () => this._postTimestamps.RemoveAt(i); } - // TLに反映 - if (!this.tw.UserStreamActive) - { - // 自分のRTはTLの更新では取得できない場合があるので、 - // 投稿時取得の有無に関わらず追加しておく - posts.ForEach(post => this._statuses.AddPost(post)); + // 自分のRTはTLの更新では取得できない場合があるので、 + // 投稿時取得の有無に関わらず追加しておく + posts.ForEach(post => this._statuses.AddPost(post)); - if (SettingManager.Common.PostAndGet) - await this.RefreshTabAsync(); - else - { - this._statuses.DistributePosts(); - this.RefreshTimeline(); - } + if (SettingManager.Common.PostAndGet) + await this.RefreshTabAsync(); + else + { + this._statuses.DistributePosts(); + this.RefreshTimeline(); } } @@ -7052,8 +6995,6 @@ private void SaveConfigsCommon() SettingManager.Common.HashIsHead = HashMgr.IsHead; SettingManager.Common.HashIsPermanent = HashMgr.IsPermanent; SettingManager.Common.HashIsNotAddToAtReply = HashMgr.IsNotAddToAtReply; - SettingManager.Common.TrackWord = tw.TrackWord; - SettingManager.Common.AllAtReply = tw.AllAtReply; SettingManager.Common.UseImageService = ImageSelector.ServiceIndex; SettingManager.Common.UseImageServiceName = ImageSelector.ServiceName; @@ -9571,28 +9512,12 @@ private void SelectListItem(DetailsListView LView , int[]? Index, int focusedInd if (flg) LView.Invalidate(bnd); } - private void StartUserStream() - { - tw.NewPostFromStream += tw_NewPostFromStream; - tw.UserStreamStarted += tw_UserStreamStarted; - tw.UserStreamStopped += tw_UserStreamStopped; - tw.PostDeleted += tw_PostDeleted; - tw.UserStreamEventReceived += tw_UserStreamEventArrived; - - this.RefreshUserStreamsMenu(); - - if (SettingManager.Common.UserstreamStartup) - tw.StartUserStream(); - } - private async void TweenMain_Shown(object sender, EventArgs e) { NotifyIcon1.Visible = true; if (this.IsNetworkAvailable()) { - StartUserStream(); - var loadTasks = new List { this.RefreshMuteUserIdsAsync(), @@ -11043,302 +10968,6 @@ private void CacheInfoMenuItem_Click(object sender, EventArgs e) MessageBox.Show(buf.ToString(), "アイコンキャッシュ使用状況"); } -#region "Userstream" - private async void tw_PostDeleted(object sender, PostDeletedEventArgs e) - { - try - { - if (InvokeRequired && !IsDisposed) - { - await this.InvokeAsync(() => - { - this._statuses.RemovePostFromAllTabs(e.StatusId, setIsDeleted: true); - if (this.CurrentTab.Contains(e.StatusId)) - { - this.PurgeListViewItemCache(); - this.CurrentListView.Update(); - var post = this.CurrentPost; - if (post != null && post.StatusId == e.StatusId) - this.DispSelectedPost(true); - } - }); - return; - } - } - catch (ObjectDisposedException) - { - return; - } - catch (InvalidOperationException) - { - return; - } - } - - private void tw_NewPostFromStream(object sender, EventArgs e) - { - if (SettingManager.Common.ReadOldPosts) - { - _statuses.SetReadHomeTab(); //新着時未読クリア - } - - this._statuses.DistributePosts(); - - _ = this.refreshThrottlingTimer.Call(); - } - - private async void tw_UserStreamStarted(object sender, EventArgs e) - { - try - { - if (InvokeRequired && !IsDisposed) - { - await this.InvokeAsync(() => this.tw_UserStreamStarted(sender, e)); - return; - } - } - catch (ObjectDisposedException) - { - return; - } - catch (InvalidOperationException) - { - return; - } - - this.RefreshUserStreamsMenu(); - this.MenuItemUserStream.Enabled = true; - - StatusLabel.Text = "UserStream Started."; - } - - private async void tw_UserStreamStopped(object sender, EventArgs e) - { - try - { - if (InvokeRequired && !IsDisposed) - { - await this.InvokeAsync(() => this.tw_UserStreamStopped(sender, e)); - return; - } - } - catch (ObjectDisposedException) - { - return; - } - catch (InvalidOperationException) - { - return; - } - - this.RefreshUserStreamsMenu(); - this.MenuItemUserStream.Enabled = true; - - StatusLabel.Text = "UserStream Stopped."; - } - - private void RefreshUserStreamsMenu() - { - if (this.tw.UserStreamActive) - { - this.MenuItemUserStream.Text = "&UserStream ▶"; - this.StopToolStripMenuItem.Text = "&Stop"; - } - else - { - this.MenuItemUserStream.Text = "&UserStream ■"; - this.StopToolStripMenuItem.Text = "&Start"; - } - } - - private async void tw_UserStreamEventArrived(object sender, UserStreamEventReceivedEventArgs e) - { - try - { - if (InvokeRequired && !IsDisposed) - { - await this.InvokeAsync(() => this.tw_UserStreamEventArrived(sender, e)); - return; - } - } - catch (ObjectDisposedException) - { - return; - } - catch (InvalidOperationException) - { - return; - } - var ev = e.EventData; - StatusLabel.Text = "Event: " + ev.Event; - NotifyEvent(ev); - if (ev.Event == "favorite" || ev.Event == "unfavorite") - { - if (this.CurrentTab.Contains(ev.Id)) - { - this.PurgeListViewItemCache(); - this.CurrentListView.Update(); - } - if (ev.Event == "unfavorite" && ev.Username.Equals(tw.Username, StringComparison.InvariantCultureIgnoreCase)) - { - var favTab = this._statuses.FavoriteTab; - favTab.EnqueueRemovePost(ev.Id, setIsDeleted: false); - } - } - } - - private void NotifyEvent(Twitter.FormattedEvent ev) - { - //新着通知 - if (BalloonRequired(ev)) - { - NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info; - var title = new StringBuilder(); - if (SettingManager.Common.DispUsername) - { - title.Append(tw.Username); - title.Append(" - "); - } - title.Append(ApplicationSettings.ApplicationName); - title.Append(" ["); - title.Append(ev.Event.ToUpper(CultureInfo.CurrentCulture)); - title.Append("] by "); - if (!MyCommon.IsNullOrEmpty(ev.Username)) - { - title.Append(ev.Username); - } - - string text; - if (!MyCommon.IsNullOrEmpty(ev.Target)) - text = ev.Target; - else - text = " "; - - if (SettingManager.Common.IsUseNotifyGrowl) - { - gh.Notify(GrowlHelper.NotifyType.UserStreamEvent, - ev.Id.ToString(), title.ToString(), text); - } - else - { - NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info; - NotifyIcon1.BalloonTipTitle = title.ToString(); - NotifyIcon1.BalloonTipText = text; - NotifyIcon1.ShowBalloonTip(500); - } - } - - //サウンド再生 - var snd = SettingManager.Common.EventSoundFile; - if (!_initial && SettingManager.Common.PlaySound && !MyCommon.IsNullOrEmpty(snd)) - { - if ((ev.Eventtype & SettingManager.Common.EventNotifyFlag) != 0 && IsMyEventNotityAsEventType(ev)) - { - try - { - var dir = Application.StartupPath; - if (Directory.Exists(Path.Combine(dir, "Sounds"))) - { - dir = Path.Combine(dir, "Sounds"); - } - using var player = new SoundPlayer(Path.Combine(dir, snd)); - player.Play(); - } - catch (Exception) - { - } - } - } - } - - private void StopToolStripMenuItem_Click(object sender, EventArgs e) - { - MenuItemUserStream.Enabled = false; - if (StopRefreshAllMenuItem.Checked) - { - StopRefreshAllMenuItem.Checked = false; - return; - } - if (this.tw.UserStreamActive) - { - tw.StopUserStream(); - } - else - { - tw.StartUserStream(); - } - } - - private static string inputTrack = ""; - - private void TrackToolStripMenuItem_Click(object sender, EventArgs e) - { - if (TrackToolStripMenuItem.Checked) - { - using (var inputForm = new InputTabName()) - { - inputForm.TabName = inputTrack; - inputForm.FormTitle = "Input track word"; - inputForm.FormDescription = "Track word"; - if (inputForm.ShowDialog() != DialogResult.OK) - { - TrackToolStripMenuItem.Checked = false; - return; - } - inputTrack = inputForm.TabName.Trim(); - } - if (!inputTrack.Equals(tw.TrackWord)) - { - tw.TrackWord = inputTrack; - this.MarkSettingCommonModified(); - TrackToolStripMenuItem.Checked = !MyCommon.IsNullOrEmpty(inputTrack); - tw.ReconnectUserStream(); - } - } - else - { - tw.TrackWord = ""; - tw.ReconnectUserStream(); - } - this.MarkSettingCommonModified(); - } - - private void AllrepliesToolStripMenuItem_Click(object sender, EventArgs e) - { - tw.AllAtReply = AllrepliesToolStripMenuItem.Checked; - this.MarkSettingCommonModified(); - tw.ReconnectUserStream(); - } - - private void EventViewerMenuItem_Click(object sender, EventArgs e) - { - if (evtDialog == null || evtDialog.IsDisposed) - { - this.evtDialog = new EventViewerDialog - { - Owner = this, - }; - - //親の中央に表示 - this.evtDialog.Location = new Point - { - X = Convert.ToInt32(this.Location.X + this.Size.Width / 2 - evtDialog.Size.Width / 2), - Y = Convert.ToInt32(this.Location.Y + this.Size.Height / 2 - evtDialog.Size.Height / 2), - }; - } - evtDialog.EventSource = tw.StoredEvent; - if (!evtDialog.Visible) - { - evtDialog.Show(this); - } - else - { - evtDialog.Activate(); - } - this.TopMost = SettingManager.Common.AlwaysTop; - } -#endregion - private void TweenRestartMenuItem_Click(object sender, EventArgs e) { MyCommon._endingFlag = true; @@ -11424,14 +11053,6 @@ private void SystemEvents_TimeChanged(object sender, EventArgs e) private void TimelineRefreshEnableChange(bool isEnable) { - if (isEnable) - { - tw.StartUserStream(); - } - else - { - tw.StopUserStream(); - } this.timelineScheduler.Enabled = isEnable; } diff --git a/OpenTween/Tween.resx b/OpenTween/Tween.resx index 141eb8489..2a28a2028 100644 --- a/OpenTween/Tween.resx +++ b/OpenTween/Tween.resx @@ -1636,48 +1636,6 @@ その他機能(&C) - - 227, 22 - - - Stop - - - 224, 6 - - - 227, 22 - - - Track - - - 227, 22 - - - All @replies - - - 224, 6 - - - Ctrl+Shift+E - - - 227, 22 - - - View Events - - - False - - - 90, 20 - - - UserStream - F1 @@ -3192,48 +3150,6 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - MenuItemUserStream - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - StopToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator40 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TrackToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - AllrepliesToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator42 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EventViewerMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - MenuItemHelp diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 5c6db1afd..92eb41e75 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -218,7 +218,6 @@ public void Initialize(string token, string tokenSecret, string username, long u } this.ResetApiStatus(); this.Api.Initialize(token, tokenSecret, userId, username); - if (SettingManager.Common.UserstreamStartup) this.ReconnectUserStream(); } internal static string PreProcessUrl(string orgData) @@ -1089,122 +1088,6 @@ public async Task GetSearch(bool read, PublicSearchTabModel tab, bool more) tab.OldestId = minimumId.Value; } - private void CreateDirectMessagesFromJson(TwitterDirectMessage[] item, MyCommon.WORKERTYPE gType, bool read) - { - foreach (var message in item) - { - var post = new PostClass(); - try - { - post.StatusId = message.Id; - - //二重取得回避 - lock (LockObj) - { - if (TabInformations.GetInstance().DirectMessageTab.Contains(post.StatusId)) continue; - } - //sender_id - //recipient_id - post.CreatedAt = MyCommon.DateTimeParse(message.CreatedAt); - //本文 - var textFromApi = message.Text; - //HTMLに整形 - post.Text = CreateHtmlAnchor(textFromApi, message.Entities, quotedStatusLink: null); - post.TextFromApi = this.ReplaceTextFromApi(textFromApi, message.Entities, quotedStatusLink: null); - post.TextFromApi = WebUtility.HtmlDecode(post.TextFromApi); - post.TextFromApi = post.TextFromApi.Replace("<3", "\u2661"); - post.AccessibleText = CreateAccessibleText(textFromApi, message.Entities, quotedStatus: null, quotedStatusLink: null); - post.AccessibleText = WebUtility.HtmlDecode(post.AccessibleText); - post.AccessibleText = post.AccessibleText.Replace("<3", "\u2661"); - post.IsFav = false; - - this.ExtractEntities(message.Entities, post.ReplyToList, post.Media); - - post.QuoteStatusIds = GetQuoteTweetStatusIds(message.Entities, quotedStatusLink: null) - .Distinct().ToArray(); - - post.ExpandedUrls = message.Entities.OfType() - .Select(x => new PostClass.ExpandedUrlInfo(x.Url, x.ExpandedUrl)) - .ToArray(); - - //以下、ユーザー情報 - TwitterUser? user; - if (gType == MyCommon.WORKERTYPE.UserStream) - { - if (this.Api.CurrentUserId == message.Recipient?.Id) - { - user = message.Sender; - post.IsMe = false; - post.IsOwl = true; - } - else - { - user = message.Recipient; - post.IsMe = true; - post.IsOwl = false; - } - } - else - { - if (gType == MyCommon.WORKERTYPE.DirectMessegeRcv) - { - user = message.Sender; - post.IsMe = false; - post.IsOwl = true; - } - else - { - user = message.Recipient; - post.IsMe = true; - post.IsOwl = false; - } - } - - if (user != null) - { - post.UserId = user.Id; - post.ScreenName = user.ScreenName; - post.Nickname = user.Name.Trim(); - post.ImageUrl = user.ProfileImageUrlHttps; - post.IsProtect = user.Protected; - post.IsMe = post.UserId == this.UserId; - } - else - { - post.UserId = 0L; - post.ScreenName = "?????"; - post.Nickname = "Unknown User"; - } - - // メモリ使用量削減 (同一のテキストであれば同一の string インスタンスを参照させる) - if (post.Text == post.TextFromApi) - post.Text = post.TextFromApi; - if (post.AccessibleText == post.TextFromApi) - post.AccessibleText = post.TextFromApi; - - // 他の発言と重複しやすい (共通化できる) 文字列は string.Intern を通す - post.ScreenName = string.Intern(post.ScreenName); - post.Nickname = string.Intern(post.Nickname); - post.ImageUrl = string.Intern(post.ImageUrl); - } - catch(Exception ex) - { - MyCommon.TraceOut(ex, MethodBase.GetCurrentMethod().Name); - MessageBox.Show("Parse Error(CreateDirectMessagesFromJson)"); - continue; - } - - post.IsRead = read; - if (post.IsMe && !read && this.ReadOwnPost) post.IsRead = true; - post.IsReply = false; - post.IsExcludeReply = false; - post.IsDm = true; - - var dmTab = TabInformations.GetInstance().DirectMessageTab; - dmTab.AddPostQueue(post); - } - } - public async Task GetDirectMessageEvents(bool read, bool backward) { this.CheckAccountState(); @@ -1868,489 +1751,25 @@ int GetWeightFromCodepoint(int codepoint) return remainWeight / config.Scale; } + public bool IsDisposed { get; private set; } = false; -#region "UserStream" - public string TrackWord { get; set; } = ""; - public bool AllAtReply { get; set; } = false; - - public event EventHandler? NewPostFromStream; - public event EventHandler? UserStreamStarted; - public event EventHandler? UserStreamStopped; - public event EventHandler? PostDeleted; - public event EventHandler? UserStreamEventReceived; - private DateTimeUtc _lastUserstreamDataReceived; - private StreamAutoConnector? userStreamConnector; - - public class FormattedEvent - { - public MyCommon.EVENTTYPE Eventtype { get; set; } - public DateTimeUtc CreatedAt { get; set; } - public string Event { get; set; } = ""; - public string Username { get; set; } = ""; - public string Target { get; set; } = ""; - public long Id { get; set; } - public bool IsMe { get; set; } - } - - public List StoredEvent { get; } = new List(); - - private readonly IReadOnlyDictionary eventTable = new Dictionary - { - ["favorite"] = MyCommon.EVENTTYPE.Favorite, - ["unfavorite"] = MyCommon.EVENTTYPE.Unfavorite, - ["follow"] = MyCommon.EVENTTYPE.Follow, - ["list_member_added"] = MyCommon.EVENTTYPE.ListMemberAdded, - ["list_member_removed"] = MyCommon.EVENTTYPE.ListMemberRemoved, - ["block"] = MyCommon.EVENTTYPE.Block, - ["unblock"] = MyCommon.EVENTTYPE.Unblock, - ["user_update"] = MyCommon.EVENTTYPE.UserUpdate, - ["deleted"] = MyCommon.EVENTTYPE.Deleted, - ["list_created"] = MyCommon.EVENTTYPE.ListCreated, - ["list_destroyed"] = MyCommon.EVENTTYPE.ListDestroyed, - ["list_updated"] = MyCommon.EVENTTYPE.ListUpdated, - ["unfollow"] = MyCommon.EVENTTYPE.Unfollow, - ["list_user_subscribed"] = MyCommon.EVENTTYPE.ListUserSubscribed, - ["list_user_unsubscribed"] = MyCommon.EVENTTYPE.ListUserUnsubscribed, - ["mute"] = MyCommon.EVENTTYPE.Mute, - ["unmute"] = MyCommon.EVENTTYPE.Unmute, - ["quoted_tweet"] = MyCommon.EVENTTYPE.QuotedTweet, - }; - - public bool IsUserstreamDataReceived - => (DateTimeUtc.Now - this._lastUserstreamDataReceived).TotalSeconds < 31; - - private void userStream_MessageReceived(ITwitterStreamMessage message) - { - this._lastUserstreamDataReceived = DateTimeUtc.Now; - - switch (message) - { - case StreamMessageStatus statusMessage: - var status = statusMessage.Status.Normalize(); - - if (status.RetweetedStatus is TwitterStatus retweetedStatus) - { - var sourceUserId = statusMessage.Status.User.Id; - var targetUserId = retweetedStatus.User.Id; - - // 自分に関係しないリツイートの場合は無視する - var selfUserId = this.UserId; - if (sourceUserId == selfUserId || targetUserId == selfUserId) - { - // 公式 RT をイベントとしても扱う - var evt = this.CreateEventFromRetweet(status); - this.StoredEvent.Insert(0, evt); - this.UserStreamEventReceived?.Invoke(this, new UserStreamEventReceivedEventArgs(evt)); - } - // 従来通り公式 RT の表示も行うため break しない - } - - this.CreatePostsFromJson(new[] { status }, MyCommon.WORKERTYPE.UserStream, null, false); - this.NewPostFromStream?.Invoke(this, EventArgs.Empty); - break; - - case StreamMessageDirectMessage dmMessage: - this.CreateDirectMessagesFromJson(new[] { dmMessage.DirectMessage }, MyCommon.WORKERTYPE.UserStream, false); - this.NewPostFromStream?.Invoke(this, EventArgs.Empty); - break; - - case StreamMessageDelete deleteMessage: - var deletedId = deleteMessage.Status?.Id ?? deleteMessage.DirectMessage?.Id; - if (deletedId == null) - break; - - this.PostDeleted?.Invoke(this, new PostDeletedEventArgs(deletedId.Value)); - - foreach (var index in MyCommon.CountDown(this.StoredEvent.Count - 1, 0)) - { - var evt = this.StoredEvent[index]; - if (evt.Id == deletedId.Value && (evt.Event == "favorite" || evt.Event == "unfavorite")) - { - this.StoredEvent.RemoveAt(index); - } - } - break; - - case StreamMessageEvent eventMessage: - this.CreateEventFromJson(eventMessage); - break; - - case StreamMessageScrubGeo scrubGeoMessage: - TabInformations.GetInstance().ScrubGeoReserve(scrubGeoMessage.UserId, scrubGeoMessage.UpToStatusId); - break; - - default: - break; - } - } - - /// - /// UserStreamsから受信した公式RTをイベントに変換します - /// - private FormattedEvent CreateEventFromRetweet(TwitterStatus status) - { - if (status.RetweetedStatus == null) - throw new InvalidOperationException(); - - return new FormattedEvent - { - Eventtype = MyCommon.EVENTTYPE.Retweet, - Event = "retweet", - CreatedAt = MyCommon.DateTimeParse(status.CreatedAt), - IsMe = status.User.Id == this.UserId, - Username = status.User.ScreenName, - Target = string.Format("@{0}:{1}", new[] - { - status.RetweetedStatus.User.ScreenName, - WebUtility.HtmlDecode(status.RetweetedStatus.FullText), - }), - Id = status.RetweetedStatus.Id, - }; - } - - private void CreateEventFromJson(StreamMessageEvent message) - { - var eventData = message.Event; - - var evt = new FormattedEvent - { - CreatedAt = MyCommon.DateTimeParse(eventData.CreatedAt), - Event = eventData.Event, - Username = eventData.Source.ScreenName, - IsMe = eventData.Source.Id == this.UserId, - Eventtype = eventTable.TryGetValue(eventData.Event, out var eventType) ? eventType : MyCommon.EVENTTYPE.None, - }; - - TwitterStreamEvent tweetEvent; - TwitterStatus tweet; - - switch (eventData.Event) - { - case "access_revoked": - case "access_unrevoked": - case "user_delete": - case "user_suspend": - return; - case "follow": - if (eventData.Target.Id == this.UserId) - { - if (!this.followerId.Contains(eventData.Source.Id)) this.followerId.Add(eventData.Source.Id); - } - else - { - return; //Block後のUndoをすると、SourceとTargetが逆転したfollowイベントが帰ってくるため。 - } - evt.Target = ""; - break; - case "unfollow": - evt.Target = "@" + eventData.Target.ScreenName; - break; - case "favorited_retweet": - case "retweeted_retweet": - return; - case "favorite": - case "unfavorite": - tweetEvent = message.ParseTargetObjectAs(); - tweet = tweetEvent.TargetObject.Normalize(); - evt.Target = "@" + tweet.User.ScreenName + ":" + WebUtility.HtmlDecode(tweet.FullText); - evt.Id = tweet.Id; - - if (SettingManager.Common.IsRemoveSameEvent) - { - if (this.StoredEvent.Any(ev => ev.Username == evt.Username && ev.Eventtype == evt.Eventtype && ev.Target == evt.Target)) - return; - } - - var tabinfo = TabInformations.GetInstance(); - - var statusId = tweet.Id; - if (!tabinfo.Posts.TryGetValue(statusId, out var post)) - break; - - if (eventData.Event == "favorite") - { - var favTab = tabinfo.FavoriteTab; - favTab.AddPostQueue(post); - - if (tweetEvent.Source.Id == this.UserId) - { - post.IsFav = true; - } - else if (tweetEvent.Target.Id == this.UserId) - { - post.FavoritedCount++; - - if (SettingManager.Common.FavEventUnread) - tabinfo.SetReadAllTab(post.StatusId, read: false); - } - } - else // unfavorite - { - if (tweetEvent.Source.Id == this.UserId) - { - post.IsFav = false; - } - else if (tweetEvent.Target.Id == this.UserId) - { - post.FavoritedCount = Math.Max(0, post.FavoritedCount - 1); - } - } - break; - case "quoted_tweet": - if (evt.IsMe) return; - - tweetEvent = message.ParseTargetObjectAs(); - tweet = tweetEvent.TargetObject.Normalize(); - evt.Target = "@" + tweet.User.ScreenName + ":" + WebUtility.HtmlDecode(tweet.FullText); - evt.Id = tweet.Id; - - if (SettingManager.Common.IsRemoveSameEvent) - { - if (this.StoredEvent.Any(ev => ev.Username == evt.Username && ev.Eventtype == evt.Eventtype && ev.Target == evt.Target)) - return; - } - break; - case "list_member_added": - case "list_member_removed": - case "list_created": - case "list_destroyed": - case "list_updated": - case "list_user_subscribed": - case "list_user_unsubscribed": - var listEvent = message.ParseTargetObjectAs(); - evt.Target = listEvent.TargetObject.FullName; - break; - case "block": - if (!TabInformations.GetInstance().BlockIds.Contains(eventData.Target.Id)) TabInformations.GetInstance().BlockIds.Add(eventData.Target.Id); - evt.Target = ""; - break; - case "unblock": - if (TabInformations.GetInstance().BlockIds.Contains(eventData.Target.Id)) TabInformations.GetInstance().BlockIds.Remove(eventData.Target.Id); - evt.Target = ""; - break; - case "user_update": - evt.Target = ""; - break; - - // Mute / Unmute - case "mute": - evt.Target = "@" + eventData.Target.ScreenName; - if (!TabInformations.GetInstance().MuteUserIds.Contains(eventData.Target.Id)) - { - TabInformations.GetInstance().MuteUserIds.Add(eventData.Target.Id); - } - break; - case "unmute": - evt.Target = "@" + eventData.Target.ScreenName; - if (TabInformations.GetInstance().MuteUserIds.Contains(eventData.Target.Id)) - { - TabInformations.GetInstance().MuteUserIds.Remove(eventData.Target.Id); - } - break; - - default: - MyCommon.TraceOut("Unknown Event:" + evt.Event + Environment.NewLine + message.Json); - break; - } - this.StoredEvent.Insert(0, evt); - - this.UserStreamEventReceived?.Invoke(this, new UserStreamEventReceivedEventArgs(evt)); - } - - private void userStream_Started() - => this.UserStreamStarted?.Invoke(this, EventArgs.Empty); - - private void userStream_Stopped() - => this.UserStreamStopped?.Invoke(this, EventArgs.Empty); - - public bool UserStreamActive - => this.userStreamConnector != null && this.userStreamConnector.IsStreamActive; - - public void StartUserStream() - { - var replies = this.AllAtReply ? "all" : null; - var streamObservable = this.Api.UserStreams(replies, this.TrackWord); - var newConnector = new StreamAutoConnector(streamObservable); - - newConnector.MessageReceived += userStream_MessageReceived; - newConnector.Started += userStream_Started; - newConnector.Stopped += userStream_Stopped; - - newConnector.Start(); - - var oldConnector = Interlocked.Exchange(ref this.userStreamConnector, newConnector); - oldConnector?.Dispose(); - } - - public void StopUserStream() - { - var oldConnector = Interlocked.Exchange(ref this.userStreamConnector, null); - oldConnector?.Dispose(); - } - - public void ReconnectUserStream() - { - if (this.userStreamConnector != null) - { - this.StartUserStream(); - } - } - - private class StreamAutoConnector : IDisposable + protected virtual void Dispose(bool disposing) { - private readonly TwitterStreamObservable streamObservable; - - public bool IsStreamActive { get; private set; } - public bool IsDisposed { get; private set; } - - public event Action? MessageReceived; - public event Action? Stopped; - public event Action? Started; - - private Task? streamTask; - private CancellationTokenSource streamCts = new CancellationTokenSource(); - - public StreamAutoConnector(TwitterStreamObservable streamObservable) - => this.streamObservable = streamObservable; - - public void Start() - { - var cts = new CancellationTokenSource(); - - this.streamCts = cts; - this.streamTask = Task.Run(async () => - { - try - { - await this.StreamLoop(cts.Token) - .ConfigureAwait(false); - } - catch (OperationCanceledException) { } - }); - } - - public void Stop() - { - this.streamCts?.Cancel(); - - // streamTask の完了を待たずに IsStreamActive を false にセットする - this.IsStreamActive = false; - this.Stopped?.Invoke(); - } - - private async Task StreamLoop(CancellationToken cancellationToken) - { - var sleep = TimeSpan.Zero; - for (; ; ) - { - if (sleep != TimeSpan.Zero) - { - await Task.Delay(sleep, cancellationToken) - .ConfigureAwait(false); - sleep = TimeSpan.Zero; - } - - if (!MyCommon.IsNetworkAvailable()) - { - sleep = TimeSpan.FromSeconds(30); - continue; - } - - this.IsStreamActive = true; - this.Started?.Invoke(); - - try - { - await this.streamObservable.ForEachAsync( - x => this.MessageReceived?.Invoke(x), - cancellationToken); - - // キャンセルされていないのにストリームが終了した場合 - sleep = TimeSpan.FromSeconds(30); - } - catch (TwitterApiException ex) when (ex.StatusCode == HttpStatusCode.Gone) - { - // UserStreams停止によるエラーの場合は長めに間隔を開ける - sleep = TimeSpan.FromMinutes(10); - } - catch (TwitterApiException) { sleep = TimeSpan.FromSeconds(30); } - catch (IOException) { sleep = TimeSpan.FromSeconds(30); } - catch (OperationCanceledException) - { - if (cancellationToken.IsCancellationRequested) - throw; - - // cancellationToken によるキャンセルではない(=タイムアウトエラー) - sleep = TimeSpan.FromSeconds(30); - } - catch (Exception ex) - { - MyCommon.ExceptionOut(ex); - sleep = TimeSpan.FromSeconds(30); - } - finally - { - this.IsStreamActive = false; - this.Stopped?.Invoke(); - } - } - } + if (this.IsDisposed) + return; - public void Dispose() + if (disposing) { - if (this.IsDisposed) - return; - - this.IsDisposed = true; - - this.Stop(); - - this.Started = null; - this.Stopped = null; - this.MessageReceived = null; + this.Api.Dispose(); } - } -#endregion - -#region "IDisposable Support" - private bool disposedValue; // 重複する呼び出しを検出するには - // IDisposable - protected virtual void Dispose(bool disposing) - { - if (!this.disposedValue) - { - if (disposing) - { - this.StopUserStream(); - } - } - this.disposedValue = true; + this.IsDisposed = true; } - // このコードは、破棄可能なパターンを正しく実装できるように Visual Basic によって追加されました。 public void Dispose() { - // このコードを変更しないでください。クリーンアップ コードを上の Dispose(bool disposing) に記述します。 Dispose(true); GC.SuppressFinalize(this); } -#endregion - } - - public class PostDeletedEventArgs : EventArgs - { - public long StatusId { get; } - - public PostDeletedEventArgs(long statusId) - => this.StatusId = statusId; - } - - public class UserStreamEventReceivedEventArgs : EventArgs - { - public Twitter.FormattedEvent EventData { get; } - - public UserStreamEventReceivedEventArgs(Twitter.FormattedEvent eventData) - => this.EventData = eventData; } } From 6c15a0a7a07a92fe9451124b1ae91379a7e9759d Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 30 Jan 2022 07:59:20 +0900 Subject: [PATCH 043/402] =?UTF-8?q?*.resx=20=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=AE=E3=83=95=E3=82=A9=E3=83=BC=E3=83=9E=E3=83=83?= =?UTF-8?q?=E3=82=BF=E3=83=BC=20(ResXcue)=20=E3=82=92=E5=B0=8E=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WinFormsデザイナーによる編集後の差分を確認しやすくするため --- OpenTween/OpenTween.csproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index a7ec6b0b3..b0ec82a31 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -753,6 +753,11 @@ + + + 1.0.1 + + + + + From 12a6b3439a3ff5a74bd9c9585550bed03bede4b2 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 30 Jan 2022 08:24:13 +0900 Subject: [PATCH 044/402] =?UTF-8?q?ResXcue=E3=81=AB=E3=82=88=E3=82=8B=20*.?= =?UTF-8?q?resx=20=E3=81=AE=E3=83=95=E3=82=A9=E3=83=BC=E3=83=9E=E3=83=83?= =?UTF-8?q?=E3=83=88=E3=82=92=E5=AE=9F=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApiInfoDialog.resx | 125 +- OpenTween/AppendSettingDialog.en.resx | 167 +- OpenTween/AppendSettingDialog.resx | 1173 ++--- OpenTween/AtIdSupplement.en.resx | 143 +- OpenTween/AtIdSupplement.resx | 343 +- OpenTween/AuthDialog.en.resx | 157 +- OpenTween/AuthDialog.resx | 441 +- OpenTween/EncryptApiKeyDialog.resx | 535 +- OpenTween/FilterDialog.en.resx | 439 +- OpenTween/FilterDialog.resx | 2599 +++------- OpenTween/HashtagManage.en.resx | 199 +- OpenTween/HashtagManage.resx | 971 +--- OpenTween/InputDialog.en.resx | 129 +- OpenTween/InputDialog.resx | 375 +- OpenTween/InputTabName.en.resx | 151 +- OpenTween/InputTabName.resx | 407 +- OpenTween/ListAvailable.en.resx | 179 +- OpenTween/ListAvailable.resx | 795 +-- OpenTween/ListManage.en.resx | 271 +- OpenTween/ListManage.resx | 1931 ++----- OpenTween/LoginDialog.en.resx | 151 +- OpenTween/LoginDialog.resx | 375 +- OpenTween/MediaSelector.en.resx | 133 +- OpenTween/MediaSelector.resx | 567 +- OpenTween/MyLists.en.resx | 147 +- OpenTween/MyLists.resx | 363 +- OpenTween/OpenURL.en.resx | 129 +- OpenTween/OpenURL.resx | 383 +- OpenTween/Properties/Resources.en.resx | 1457 ++---- OpenTween/Properties/Resources.resx | 1535 ++---- OpenTween/SearchWordDialog.en.resx | 191 +- OpenTween/SearchWordDialog.resx | 743 +-- OpenTween/SendErrorReportForm.en.resx | 179 +- OpenTween/SendErrorReportForm.resx | 621 +-- OpenTween/Setting/Panel/ActionPanel.en.resx | 271 +- OpenTween/Setting/Panel/ActionPanel.resx | 1107 +--- OpenTween/Setting/Panel/BasedPanel.en.resx | 147 +- OpenTween/Setting/Panel/BasedPanel.resx | 335 +- .../Setting/Panel/ConnectionPanel.en.resx | 159 +- OpenTween/Setting/Panel/ConnectionPanel.resx | 451 +- .../Setting/Panel/CooperatePanel.en.resx | 183 +- OpenTween/Setting/Panel/CooperatePanel.resx | 1251 ++--- OpenTween/Setting/Panel/FontPanel.en.resx | 231 +- OpenTween/Setting/Panel/FontPanel.resx | 1291 ++--- OpenTween/Setting/Panel/FontPanel2.en.resx | 243 +- OpenTween/Setting/Panel/FontPanel2.resx | 1307 ++--- OpenTween/Setting/Panel/GetCountPanel.en.resx | 199 +- OpenTween/Setting/Panel/GetCountPanel.resx | 763 +-- .../Setting/Panel/GetPeriodPanel.en.resx | 187 +- OpenTween/Setting/Panel/GetPeriodPanel.resx | 659 +-- OpenTween/Setting/Panel/NotifyPanel.en.resx | 125 +- OpenTween/Setting/Panel/NotifyPanel.resx | 143 +- OpenTween/Setting/Panel/PreviewPanel.en.resx | 369 +- OpenTween/Setting/Panel/PreviewPanel.resx | 949 +--- OpenTween/Setting/Panel/ProxyPanel.en.resx | 191 +- OpenTween/Setting/Panel/ProxyPanel.resx | 583 +-- OpenTween/Setting/Panel/ShortUrlPanel.en.resx | 171 +- OpenTween/Setting/Panel/ShortUrlPanel.resx | 467 +- OpenTween/Setting/Panel/StartupPanel.en.resx | 159 +- OpenTween/Setting/Panel/StartupPanel.resx | 307 +- OpenTween/Setting/Panel/TweetActPanel.en.resx | 191 +- OpenTween/Setting/Panel/TweetActPanel.resx | 535 +- OpenTween/Setting/Panel/TweetPrvPanel.en.resx | 199 +- OpenTween/Setting/Panel/TweetPrvPanel.resx | 739 +-- OpenTween/TabsDialog.en.resx | 137 +- OpenTween/TabsDialog.resx | 259 +- OpenTween/Tween.en.resx | 1733 ++----- OpenTween/Tween.resx | 4607 ++++------------- OpenTween/TweenAboutBox.en.resx | 157 +- OpenTween/TweenAboutBox.resx | 545 +- OpenTween/TweetDetailsView.en.resx | 247 +- OpenTween/TweetDetailsView.resx | 1091 +--- OpenTween/TweetThumbnail.en.resx | 183 +- OpenTween/TweetThumbnail.resx | 335 +- OpenTween/UpdateDialog.en.resx | 141 +- OpenTween/UpdateDialog.resx | 395 +- OpenTween/UserInfoDialog.en.resx | 447 +- OpenTween/UserInfoDialog.resx | 1919 ++----- OpenTween/WaitingDialog.resx | 223 +- 79 files changed, 9328 insertions(+), 35507 deletions(-) diff --git a/OpenTween/ApiInfoDialog.resx b/OpenTween/ApiInfoDialog.resx index 1af7de150..cabc33e77 100644 --- a/OpenTween/ApiInfoDialog.resx +++ b/OpenTween/ApiInfoDialog.resx @@ -1,120 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file + diff --git a/OpenTween/AppendSettingDialog.en.resx b/OpenTween/AppendSettingDialog.en.resx index 5f489be75..c8ca1fa2b 100644 --- a/OpenTween/AppendSettingDialog.en.resx +++ b/OpenTween/AppendSettingDialog.en.resx @@ -1,124 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - + Settings + Cancel + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQwAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl @@ -138,10 +28,8 @@ SXNDaGVja2VkCkltYWdlSW5kZXgISW1hZ2VLZXkSU2VsZWN0ZWRJbWFnZUluZGV4EFNlbGVjdGVkSW1h Z2VLZXkKQ2hpbGRDb3VudAEBAQAAAQABAAEICAgCAAAABhIAAAAGQ291bnRzCQQAAAAGFAAAAAxHZXRD b3VudE5vZGUA/////wkEAAAA/////wkEAAAAAAAAAAs= - - - - + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQoAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl @@ -152,10 +40,8 @@ b29sVGlwVGV4dAROYW1lCUlzQ2hlY2tlZApJbWFnZUluZGV4CEltYWdlS2V5ElNlbGVjdGVkSW1hZ2VJ bmRleBBTZWxlY3RlZEltYWdlS2V5CkNoaWxkQ291bnQBAQEAAAEAAQABCAgIAgAAAAYIAAAAClBvc3Qg dHdlZXQJBAAAAAYKAAAADFR3ZWV0QWN0Tm9kZQD/////CQQAAAD/////CQQAAAAAAAAACw== - - - - + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQsAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl @@ -171,10 +57,8 @@ bWFnZUtleRJTZWxlY3RlZEltYWdlSW5kZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAAB AAEAAQgICAIAAAAGDQAAABJFdmVudCBOb3RpZmljYXRpb24JBAAAAAYPAAAACk5vdGlmeU5vZGUA//// /wkEAAAA/////wkEAAAAAAAAAAs= - - - - + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQoAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl @@ -185,10 +69,8 @@ cFRleHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJbWFnZUtleRJTZWxlY3RlZEltYWdlSW5kZXgQ U2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAABAAEAAQgICAIAAAAGCAAAAAtCYWNrZ3JvdW5k cwkEAAAABgoAAAAJRm9udE5vZGUyAP////8JBAAAAP////8JBAAAAAAAAAAL - - - - + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQwAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl @@ -208,14 +90,5 @@ C1Rvb2xUaXBUZXh0BE5hbWUJSXNDaGVja2VkCkltYWdlSW5kZXgISW1hZ2VLZXkSU2VsZWN0ZWRJbWFn ZUluZGV4EFNlbGVjdGVkSW1hZ2VLZXkKQ2hpbGRDb3VudAEBAQAAAQABAAEICAgCAAAABhIAAAALU2hv cnRlbiBVUkwJBAAAAAYUAAAADFNob3J0VXJsTm9kZQD/////CQQAAAD/////CQQAAAAAAAAACw== - - - - - - Cancel - - - Settings - - \ No newline at end of file + + diff --git a/OpenTween/AppendSettingDialog.resx b/OpenTween/AppendSettingDialog.resx index 04a93ea1c..df47cd5b0 100644 --- a/OpenTween/AppendSettingDialog.resx +++ b/OpenTween/AppendSettingDialog.resx @@ -1,169 +1,253 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - 7 - - - - False - - - OK - - - - - - False - - - False - - - $this - - - 0 - - - ShortUrlPanel - - - Fill - - - 0, 0 - - - ToolTip1 - - - Fill - - - CenterParent - - - + 96, 96 + 691, 403 + True + CenterParent + + + 82 + AppendSettingDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + ActionPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.ActionPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 12 + BasedPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.BasedPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 5 + Cancel + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ColorDialog1 + System.Windows.Forms.ColorDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ConnectionPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.ConnectionPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 10 + CooperatePanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.CooperatePanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 8 + FontDialog1 + System.Windows.Forms.FontDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FontPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.FontPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 13 + FontPanel2 + SplitContainer1.Panel2 + OpenTween.Setting.Panel.FontPanel2, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 14 + GetCountPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.GetCountPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 3 + GetPeriodPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.GetPeriodPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 11 + NotifyPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.NotifyPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 7 + PreviewPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.PreviewPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 1 + ProxyPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.ProxyPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 9 + Save + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + ShortUrlPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.ShortUrlPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 4 + SplitContainer1 + SplitContainer1.Panel1 + SplitContainer1 + System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + SplitContainer1.Panel2 + SplitContainer1 + System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + $this + System.Windows.Forms.SplitContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + StartupPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.StartupPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 0 + ToolTip1 + System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TreeViewSetting + SplitContainer1.Panel1 + System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TweetActPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.TweetActPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 2 + TweetPrvPanel + SplitContainer1.Panel2 + OpenTween.Setting.Panel.TweetPrvPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 6 + Fill + False + 0, 0 + 519, 368 + 5 + + False + Fill + False + 0, 0 + 519, 368 + 0 + + False + NoControl + 604, 374 + 75, 23 + 4 + キャンセル + + 140, 17 + Fill + False + 0, 0 + 519, 368 + 11 + + False + Fill + False + 0, 0 + 519, 368 + 12 + + False + 17, 17 + Fill + False + 0, 0 + 519, 368 + 9 + + False + Fill + False + 0, 0 + 519, 368 + 10 + + False + Fill + False + 0, 0 + 519, 368 + 3 + + False + Fill + False + 0, 0 + 519, 368 + 1 + + False + Fill + False + 0, 0 + 519, 368 + 12 + + False + Fill + False + 0, 0 + 20, 10, 20, 10 + 519, 368 + 7 + + False + Fill + False + 0, 0 + 519, 368 + 12 + + False + NoControl + 521, 374 + 75, 23 + 3 + OK + + Fill + False + 0, 0 + 519, 368 + 13 + + False + Top + True + 0, 0 + + + 691, 368 + 168 + 0 + + Fill + False + 0, 0 + 20, 20, 20, 20 + 519, 368 + 2 + + False + 268, 17 + Fill + 0, 0 + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w + LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 + ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQ0AAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl + ZApJbWFnZUluZGV4CEltYWdlS2V5ElNlbGVjdGVkSW1hZ2VJbmRleBBTZWxlY3RlZEltYWdlS2V5CkNo + aWxkQ291bnQJY2hpbGRyZW4wCWNoaWxkcmVuMQljaGlsZHJlbjIIVXNlckRhdGEBAQEAAAEAAQAEBAQB + AQgICB1TeXN0ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQIAAAAdU3lzdGVtLldpbmRvd3MuRm9ybXMu + VHJlZU5vZGUCAAAAHVN5c3RlbS5XaW5kb3dzLkZvcm1zLlRyZWVOb2RlAgAAAAIAAAAGAwAAAAbln7rm + nKwGBAAAAAAGBQAAAAlCYXNlZE5vZGUA/////wkEAAAA/////wkEAAAAAwAAAAkHAAAACQgAAAAJCQAA + AAkEAAAABQcAAAAdU3lzdGVtLldpbmRvd3MuRm9ybXMuVHJlZU5vZGUJAAAABFRleHQLVG9vbFRpcFRl + eHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJbWFnZUtleRJTZWxlY3RlZEltYWdlSW5kZXgQU2Vs + ZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAABAAEAAQgICAIAAAAGCwAAAAzmm7TmlrDplpPpmpQJ + BAAAAAYNAAAAClBlcmlvZE5vZGUA/////wkEAAAA/////wkEAAAAAAAAAAUIAAAAHVN5c3RlbS5XaW5k + b3dzLkZvcm1zLlRyZWVOb2RlCQAAAARUZXh0C1Rvb2xUaXBUZXh0BE5hbWUJSXNDaGVja2VkCkltYWdl + SW5kZXgISW1hZ2VLZXkSU2VsZWN0ZWRJbWFnZUluZGV4EFNlbGVjdGVkSW1hZ2VLZXkKQ2hpbGRDb3Vu + dAEBAQAAAQABAAEICAgCAAAABg8AAAAS6LW35YuV5pmC44Gu5YuV5L2cCQQAAAAGEQAAAAtTdGFydFVw + Tm9kZQD/////CQQAAAD/////CQQAAAAAAAAABQkAAAAdU3lzdGVtLldpbmRvd3MuRm9ybXMuVHJlZU5v + ZGUJAAAABFRleHQLVG9vbFRpcFRleHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJbWFnZUtleRJT + ZWxlY3RlZEltYWdlSW5kZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAABAAEAAQgICAIA + AAAGEwAAAAzlj5blvpfku7bmlbAJBAAAAAYVAAAADEdldENvdW50Tm9kZQD/////CQQAAAD/////CQQA + AAAAAAAACw== + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQoAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl @@ -174,483 +258,8 @@ bFRpcFRleHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJbWFnZUtleRJTZWxlY3RlZEltYWdlSW5k ZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAABAAEAAQgICAIAAAAGCAAAAAbmipXnqL8J BAAAAAYKAAAADFR3ZWV0QWN0Tm9kZQD/////CQQAAAD/////CQQAAAAAAAAACw== - - - - 519, 368 - - - 0 - - - 519, 368 - - - FontPanel - - - 0, 0 - - - False - - - 7 - - - False - - - 13 - - - 691, 368 - - - False - - - False - - - 519, 368 - - - - AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w - LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQwAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl - ZApJbWFnZUluZGV4CEltYWdlS2V5ElNlbGVjdGVkSW1hZ2VJbmRleBBTZWxlY3RlZEltYWdlS2V5CkNo - aWxkQ291bnQJY2hpbGRyZW4wCWNoaWxkcmVuMQljaGlsZHJlbjIBAQEAAAEAAQAEBAQBCAgIHVN5c3Rl - bS5XaW5kb3dzLkZvcm1zLlRyZWVOb2RlAgAAAB1TeXN0ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQIA - AAAdU3lzdGVtLldpbmRvd3MuRm9ybXMuVHJlZU5vZGUCAAAAAgAAAAYDAAAABumAmuS/oQYEAAAAAAYF - AAAADkNvbm5lY3Rpb25Ob2RlAP////8JBAAAAP////8JBAAAAAMAAAAJBwAAAAkIAAAACQkAAAAFBwAA - AB1TeXN0ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQkAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlz - Q2hlY2tlZApJbWFnZUluZGV4CEltYWdlS2V5ElNlbGVjdGVkSW1hZ2VJbmRleBBTZWxlY3RlZEltYWdl - S2V5CkNoaWxkQ291bnQBAQEAAAEAAQABCAgIAgAAAAYKAAAADOODl+ODreOCreOCtwkEAAAABgwAAAAJ - UHJveHlOb2RlAP////8JBAAAAP////8JBAAAAAAAAAAFCAAAAB1TeXN0ZW0uV2luZG93cy5Gb3Jtcy5U - cmVlTm9kZQkAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tlZApJbWFnZUluZGV4CEltYWdl - S2V5ElNlbGVjdGVkSW1hZ2VJbmRleBBTZWxlY3RlZEltYWdlS2V5CkNoaWxkQ291bnQBAQEAAAEAAQAB - CAgIAgAAAAYOAAAAEumAo+aQuuOCteODvOODk+OCuQkEAAAABhAAAAANQ29vcGVyYXRlTm9kZQD///// - CQQAAAD/////CQQAAAAAAAAABQkAAAAdU3lzdGVtLldpbmRvd3MuRm9ybXMuVHJlZU5vZGUJAAAABFRl - eHQLVG9vbFRpcFRleHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJbWFnZUtleRJTZWxlY3RlZElt - YWdlSW5kZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAABAAEAAQgICAIAAAAGEgAAAAnn - n63nuK5VUkwJBAAAAAYUAAAADFNob3J0VXJsTm9kZQD/////CQQAAAD/////CQQAAAAAAAAACw== - - - - False - - - SplitContainer1.Panel1 - - - OpenTween.Setting.Panel.PreviewPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - SplitContainer1 - - - 3 - - - 0, 0 - - - Fill - - - False - - - ProxyPanel - - - 519, 368 - - - 0 - - - $this - - - 0, 0 - - - 20, 20, 20, 20 - - - Fill - - - 2 - - - 0 - - - Fill - - - キャンセル - - - False - - - 12 - - - - - - Fill - - - 10 - - - System.Windows.Forms.ColorDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer1.Panel2 - - - 519, 368 - - - TweetActPanel - - - False - - - 0 - - - False - - - 0, 0 - - - 20, 10, 20, 10 - - - 2 - - - OpenTween.Setting.Panel.ActionPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 604, 374 - - - 75, 23 - - - Fill - - - False - - - OpenTween.Setting.Panel.ProxyPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 14 - - - Fill - - - OpenTween.Setting.Panel.NotifyPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 3 - - - - - - Fill - - - 519, 368 - - - 1 - - - $this - - - SplitContainer1.Panel2 - - - BasedPanel - - - ColorDialog1 - - - - - - 4 - - - 11 - - - False - - - 6 - - - 0, 0 - - - False - - - 519, 368 - - - 96, 96 - - - Fill - - - SplitContainer1.Panel2 - - - 5 - - - OpenTween.Setting.Panel.ConnectionPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 1 - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Windows.Forms.FontDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 12 - - - 1 - - - False - - - Fill - - - False - - - ConnectionPanel - - - ActionPanel - - - OpenTween.Setting.Panel.TweetPrvPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - - - - 519, 368 - - - SplitContainer1.Panel2 - - - 12 - - - False - - - GetCountPanel - - - System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - - False - - - - - - TweetPrvPanel - - - TreeViewSetting - - - SplitContainer1 - - - SplitContainer1.Panel1 - - - OpenTween.Setting.Panel.FontPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - - - - 6 - - - - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - - 519, 368 - - - 0, 0 - - - - - - 8 - - - False - - - OpenTween.Setting.Panel.ShortUrlPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 0, 0 - - - SplitContainer1 - - - FontPanel2 - - - False - - - Fill - - - 519, 368 - - - False - - - SplitContainer1.Panel2 - - - OpenTween.Setting.Panel.FontPanel2, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - - - - Top - - - - - - 5 - - - False - - - False - - - 0, 0 - - - 9 - - - False - - - 0, 0 - - - FontDialog1 - - - - - - StartupPanel - - - 75, 23 - - - 519, 368 - - - Save - - - NotifyPanel - - - OpenTween.Setting.Panel.StartupPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - OpenTween.Setting.Panel.TweetActPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - False - - - CooperatePanel - - - Fill - - - 519, 368 - - - Fill - - - 0 - - - SplitContainer1.Panel2 - - - + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQsAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl @@ -666,25 +275,8 @@ bmRleAhJbWFnZUtleRJTZWxlY3RlZEltYWdlSW5kZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50 AQEBAAABAAEAAQgICAIAAAAGDQAAABLjgqTjg5njg7Pjg4jpgJrnn6UJBAAAAAYPAAAACk5vdGlmeU5v ZGUA/////wkEAAAA/////wkEAAAAAAAAAAs= - - - - SplitContainer1.Panel2 - - - 4 - - - 519, 368 - - - - - - SplitContainer1.Panel2 - - - + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQoAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl @@ -695,228 +287,43 @@ C1Rvb2xUaXBUZXh0BE5hbWUJSXNDaGVja2VkCkltYWdlSW5kZXgISW1hZ2VLZXkSU2VsZWN0ZWRJbWFn ZUluZGV4EFNlbGVjdGVkSW1hZ2VLZXkKQ2hpbGRDb3VudAEBAQAAAQABAAEICAgCAAAABggAAAAN44OV 44Kp44Oz44OIMgkEAAAABgoAAAAJRm9udE5vZGUyAP////8JBAAAAP////8JBAAAAAAAAAAL - - - - 0, 0 - - - 519, 368 - - - System.Windows.Forms.SplitContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 2 - - - SplitContainer1.Panel2 - - - True - - - - - - Fill - - - - - - False - - - NoControl - - - System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer1.Panel2 - - - SplitContainer1.Panel2 - - - - - - 691, 403 - - - 0, 0 - - - 8 - - - SplitContainer1.Panel2 - - - SplitContainer1.Panel2 - - - 0, 0 - - - False - - - - - - 519, 368 - - - + + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAB1TeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQ0AAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl + ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQwAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tl ZApJbWFnZUluZGV4CEltYWdlS2V5ElNlbGVjdGVkSW1hZ2VJbmRleBBTZWxlY3RlZEltYWdlS2V5CkNo - aWxkQ291bnQJY2hpbGRyZW4wCWNoaWxkcmVuMQljaGlsZHJlbjIIVXNlckRhdGEBAQEAAAEAAQAEBAQB - AQgICB1TeXN0ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQIAAAAdU3lzdGVtLldpbmRvd3MuRm9ybXMu - VHJlZU5vZGUCAAAAHVN5c3RlbS5XaW5kb3dzLkZvcm1zLlRyZWVOb2RlAgAAAAIAAAAGAwAAAAbln7rm - nKwGBAAAAAAGBQAAAAlCYXNlZE5vZGUA/////wkEAAAA/////wkEAAAAAwAAAAkHAAAACQgAAAAJCQAA - AAkEAAAABQcAAAAdU3lzdGVtLldpbmRvd3MuRm9ybXMuVHJlZU5vZGUJAAAABFRleHQLVG9vbFRpcFRl - eHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJbWFnZUtleRJTZWxlY3RlZEltYWdlSW5kZXgQU2Vs - ZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAABAAEAAQgICAIAAAAGCwAAAAzmm7TmlrDplpPpmpQJ - BAAAAAYNAAAAClBlcmlvZE5vZGUA/////wkEAAAA/////wkEAAAAAAAAAAUIAAAAHVN5c3RlbS5XaW5k - b3dzLkZvcm1zLlRyZWVOb2RlCQAAAARUZXh0C1Rvb2xUaXBUZXh0BE5hbWUJSXNDaGVja2VkCkltYWdl - SW5kZXgISW1hZ2VLZXkSU2VsZWN0ZWRJbWFnZUluZGV4EFNlbGVjdGVkSW1hZ2VLZXkKQ2hpbGRDb3Vu - dAEBAQAAAQABAAEICAgCAAAABg8AAAAS6LW35YuV5pmC44Gu5YuV5L2cCQQAAAAGEQAAAAtTdGFydFVw - Tm9kZQD/////CQQAAAD/////CQQAAAAAAAAABQkAAAAdU3lzdGVtLldpbmRvd3MuRm9ybXMuVHJlZU5v - ZGUJAAAABFRleHQLVG9vbFRpcFRleHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJbWFnZUtleRJT - ZWxlY3RlZEltYWdlSW5kZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAABAAEAAQgICAIA - AAAGEwAAAAzlj5blvpfku7bmlbAJBAAAAAYVAAAADEdldENvdW50Tm9kZQD/////CQQAAAD/////CQQA - AAAAAAAACw== - - - - 0, 0 - - - Fill - - - NoControl - - - Cancel - - - 0, 0 - - - OpenTween.Setting.Panel.GetCountPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - GetPeriodPanel - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - - - - 13 - - - 168, 368 - - - PreviewPanel - - - OpenTween.Setting.Panel.CooperatePanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 1 - - - 12 - - - SplitContainer1.Panel2 - - - OpenTween.Setting.Panel.GetPeriodPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 0, 0 - - - - - - 9 - - - OpenTween.Setting.Panel.BasedPanel, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 521, 374 - - - System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 0, 0 - - - - - - 3 - - - System.Windows.Forms.TreeView, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - False - - - False - - - SplitContainer1.Panel2 - - - 10 - - - SplitContainer1.Panel2 - - - 168 - - - 11 - - - 0 - - - AppendSettingDialog - - - - - - 17, 17 - - - True - - - 268, 17 - - - 82 - - - 140, 17 - - \ No newline at end of file + aWxkQ291bnQJY2hpbGRyZW4wCWNoaWxkcmVuMQljaGlsZHJlbjIBAQEAAAEAAQAEBAQBCAgIHVN5c3Rl + bS5XaW5kb3dzLkZvcm1zLlRyZWVOb2RlAgAAAB1TeXN0ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQIA + AAAdU3lzdGVtLldpbmRvd3MuRm9ybXMuVHJlZU5vZGUCAAAAAgAAAAYDAAAABumAmuS/oQYEAAAAAAYF + AAAADkNvbm5lY3Rpb25Ob2RlAP////8JBAAAAP////8JBAAAAAMAAAAJBwAAAAkIAAAACQkAAAAFBwAA + AB1TeXN0ZW0uV2luZG93cy5Gb3Jtcy5UcmVlTm9kZQkAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlz + Q2hlY2tlZApJbWFnZUluZGV4CEltYWdlS2V5ElNlbGVjdGVkSW1hZ2VJbmRleBBTZWxlY3RlZEltYWdl + S2V5CkNoaWxkQ291bnQBAQEAAAEAAQABCAgIAgAAAAYKAAAADOODl+ODreOCreOCtwkEAAAABgwAAAAJ + UHJveHlOb2RlAP////8JBAAAAP////8JBAAAAAAAAAAFCAAAAB1TeXN0ZW0uV2luZG93cy5Gb3Jtcy5U + cmVlTm9kZQkAAAAEVGV4dAtUb29sVGlwVGV4dAROYW1lCUlzQ2hlY2tlZApJbWFnZUluZGV4CEltYWdl + S2V5ElNlbGVjdGVkSW1hZ2VJbmRleBBTZWxlY3RlZEltYWdlS2V5CkNoaWxkQ291bnQBAQEAAAEAAQAB + CAgIAgAAAAYOAAAAEumAo+aQuuOCteODvOODk+OCuQkEAAAABhAAAAANQ29vcGVyYXRlTm9kZQD///// + CQQAAAD/////CQQAAAAAAAAABQkAAAAdU3lzdGVtLldpbmRvd3MuRm9ybXMuVHJlZU5vZGUJAAAABFRl + eHQLVG9vbFRpcFRleHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJbWFnZUtleRJTZWxlY3RlZElt + YWdlSW5kZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAABAAEAAQgICAIAAAAGEgAAAAnn + n63nuK5VUkwJBAAAAAYUAAAADFNob3J0VXJsTm9kZQD/////CQQAAAD/////CQQAAAAAAAAACw== + + 168, 368 + 0 + + Fill + False + 0, 0 + 519, 368 + 6 + + False + Fill + False + 0, 0 + 519, 368 + 8 + + False + diff --git a/OpenTween/AtIdSupplement.en.resx b/OpenTween/AtIdSupplement.en.resx index 7190bef36..7fed387ab 100644 --- a/OpenTween/AtIdSupplement.en.resx +++ b/OpenTween/AtIdSupplement.en.resx @@ -1,133 +1,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 201, 19 - - - 201, 12 - - - You can change the setting to disable. - - - 201, 37 - - \ No newline at end of file + 201, 37 + 201, 12 + You can change the setting to disable. + 201, 19 + diff --git a/OpenTween/AtIdSupplement.resx b/OpenTween/AtIdSupplement.resx index 7a2bf1773..223b22dda 100644 --- a/OpenTween/AtIdSupplement.resx +++ b/OpenTween/AtIdSupplement.resx @@ -1,282 +1,63 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 1, -32 - - - 160, 12 - - - 8 - - - 設定で自動表示をオフにできます - - - Label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Fill - - - Disable - - - 0, 0 - - - 162, 19 - - - 7 - - - TextId - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - NoControl - - - 82, 67 - - - 75, 23 - - - 6 - - - Button2 - - - ButtonCancel - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - NoControl - - - 0, 67 - - - 75, 23 - - - 5 - - - Button1 - - - ButtonOK - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 2, 22 - - - 160, 12 - - - 9 - - - 設定で自動表示をオフにできます - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 96, 96 - - - 162, 36 - - - CenterParent - - - AtIdSupplement - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 162, 36 + True + CenterParent + AtIdSupplement + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + ButtonCancel + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + ButtonOK + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + Label1 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + label2 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TextId + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + NoControl + 82, 67 + 75, 23 + 6 + Button2 + NoControl + 0, 67 + 75, 23 + 5 + Button1 + True + NoControl + 1, -32 + 160, 12 + 8 + 設定で自動表示をオフにできます + True + NoControl + 2, 22 + 160, 12 + 9 + 設定で自動表示をオフにできます + Fill + Disable + 0, 0 + 162, 19 + 7 + diff --git a/OpenTween/AuthDialog.en.resx b/OpenTween/AuthDialog.en.resx index abbcc206d..c69ce4891 100644 --- a/OpenTween/AuthDialog.en.resx +++ b/OpenTween/AuthDialog.en.resx @@ -1,143 +1,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 190, 12 - - - Access URL bellow in your browser: - - - 176, 12 - - - Allow the app and input your PIN: - - - PIN Code - - - &Cancel - - - - NoControl - - \ No newline at end of file + NoControl + &Cancel + 190, 12 + Access URL bellow in your browser: + 176, 12 + Allow the app and input your PIN: + PIN Code + diff --git a/OpenTween/AuthDialog.resx b/OpenTween/AuthDialog.resx index 6ad06ee4b..fb4f2a68a 100644 --- a/OpenTween/AuthDialog.resx +++ b/OpenTween/AuthDialog.resx @@ -1,355 +1,88 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - 12, 24 - - - - 3, 15, 3, 15 - - - 359, 15 - - - 0 - - - 下記のURLにブラウザでアクセスし、内容を確認の上で認証を行って下さい: - - - - label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - 24, 69 - - - 15, 15, 15, 15 - - - 396, 15 - - - 1 - - - linkLabel1 - - - AuthLinkLabel - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - 12, 114 - - - 3, 15, 3, 15 - - - 232, 15 - - - 2 - - - 認証後に表示されるPINコードを入力して下さい - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - PINコード - - - Top, Left, Right - - - MS UI Gothic, 24pt - - - 127, 147 - - - 190, 48 - - - 3 - - - Center - - - PinTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Bottom, Right - - - True - - - 2 - - - True - - - 84, 3 - - - 86, 25 - - - 1 - - - キャンセル (&C) - - - CancelBtn - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 0 - - - True - - - 3, 3 - - - 75, 25 - - - 0 - - - &OK - - - OKBtn - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 1 - - - 259, 201 - - - 1 - - - 173, 31 - - - 4 - - - tableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="CancelBtn" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="OKBtn" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0" /><Rows Styles="Percent,100" /></TableLayoutSettings> - - - True - - - 96, 96 - - - 444, 244 - - - CenterScreen - - - AuthDialog - - - AuthDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 444, 244 + True + CenterScreen + AuthDialog + AuthDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + AuthLinkLabel + $this + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + CancelBtn + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + label1 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + label2 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + OKBtn + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + PinTextBox + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + tableLayoutPanel1 + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + 24, 69 + 15, 15, 15, 15 + 396, 15 + 1 + linkLabel1 + True + 84, 3 + 86, 25 + 1 + キャンセル (&C) + True + 12, 24 + 3, 15, 3, 15 + 359, 15 + 0 + 下記のURLにブラウザでアクセスし、内容を確認の上で認証を行って下さい: + + True + 12, 114 + 3, 15, 3, 15 + 232, 15 + 2 + 認証後に表示されるPINコードを入力して下さい + True + 3, 3 + 75, 25 + 0 + &OK + PINコード + Top, Left, Right + MS UI Gothic, 24pt + 127, 147 + 190, 48 + 3 + Center + Bottom, Right + True + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="CancelBtn" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="OKBtn" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0" /><Rows Styles="Percent,100" /></TableLayoutSettings> + 259, 201 + 1 + 173, 31 + 4 + diff --git a/OpenTween/EncryptApiKeyDialog.resx b/OpenTween/EncryptApiKeyDialog.resx index 2cffda287..741b3854f 100644 --- a/OpenTween/EncryptApiKeyDialog.resx +++ b/OpenTween/EncryptApiKeyDialog.resx @@ -1,426 +1,111 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Left, Right - - - - True - - - - 3, 33 - - - 105, 12 - - - 2 - - - 暗号化パスワード - - - label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 6 - - - Left, Right - - - 114, 5 - - - 3, 3, 3, 0 - - - 221, 19 - - - 1 - - - textBoxPlainText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 2 - - - Left, Right - - - 114, 31 - - - 3, 3, 3, 0 - - - 221, 19 - - - 3 - - - textBoxPassword - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 7 - - - Left, Right - - - 114, 83 - - - 3, 3, 3, 0 - - - 221, 19 - - - 6 - - - textBoxEncryptedText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 3 - - - Left, Right - - - True - - - 3, 7 - - - 105, 12 - - - 0 - - - 暗号化する文字列 - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 0 - - - Left, Right - - - True - - - 3, 85 - - - 105, 12 - - - 5 - - - 暗号化された文字列 - - - label3 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 4 - - - Top, Bottom, Left, Right - - - True - - - GrowAndShrink - - - Top, Bottom, Left, Right - - - 2 - - - Top, Bottom, Right - - - True - - - GrowAndShrink - - - 250, 107 - - - 3, 3, 3, 0 - - - 10, 0, 10, 0 - - - 85, 23 - - - 7 - - - 閉じる (&C) - - - buttonClose - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 1 - - - 12, 9 - - - 3, 0, 3, 3 - - - 5 - - - 338, 130 - - - 0 - - - tableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label2" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonClose" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textBoxPlainText" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textBoxEncryptedText" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label3" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonEncrypt" Row="2" RowSpan="1" Column="0" ColumnSpan="2" /><Control Name="label1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textBoxPassword" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0" /><Rows Styles="Percent,20,Percent,20,Percent,20,Percent,20,Percent,20" /></TableLayoutSettings> - - - 3, 55 - - - 3, 3, 3, 0 - - - 332, 23 - - - 4 - - - 暗号化 - - - buttonEncrypt - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 5 - - - True - - - 96, 96 - - - 362, 151 - - - CenterParent - - - APIキー暗号化 - - - EncryptApiKeyDialog - - - OpenTween.OTBaseForm, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 362, 151 + True + CenterParent + APIキー暗号化 + EncryptApiKeyDialog + OpenTween.OTBaseForm, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null + buttonClose + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + buttonEncrypt + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + label1 + tableLayoutPanel1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + label2 + tableLayoutPanel1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + label3 + tableLayoutPanel1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + tableLayoutPanel1 + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + textBoxEncryptedText + tableLayoutPanel1 + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + textBoxPassword + tableLayoutPanel1 + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + textBoxPlainText + tableLayoutPanel1 + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Top, Bottom, Right + True + GrowAndShrink + 250, 107 + 3, 3, 3, 0 + 10, 0, 10, 0 + 85, 23 + 7 + 閉じる (&C) + Top, Bottom, Left, Right + True + GrowAndShrink + 3, 55 + 3, 3, 3, 0 + 332, 23 + 4 + 暗号化 + Left, Right + True + 3, 33 + 105, 12 + 2 + 暗号化パスワード + Left, Right + True + 3, 7 + 105, 12 + 0 + 暗号化する文字列 + Left, Right + True + 3, 85 + 105, 12 + 5 + 暗号化された文字列 + Top, Bottom, Left, Right + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="label2" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonClose" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textBoxPlainText" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textBoxEncryptedText" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="label3" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonEncrypt" Row="2" RowSpan="1" Column="0" ColumnSpan="2" /><Control Name="label1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textBoxPassword" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0" /><Rows Styles="Percent,20,Percent,20,Percent,20,Percent,20,Percent,20" /></TableLayoutSettings> + 12, 9 + 3, 0, 3, 3 + 5 + 338, 130 + 0 + Left, Right + 114, 83 + 3, 3, 3, 0 + 221, 19 + 6 + Left, Right + 114, 31 + 3, 3, 3, 0 + 221, 19 + 3 + Left, Right + 114, 5 + 3, 3, 3, 0 + 221, 19 + 1 + diff --git a/OpenTween/FilterDialog.en.resx b/OpenTween/FilterDialog.en.resx index f399eea03..c49e8243c 100644 --- a/OpenTween/FilterDialog.en.resx +++ b/OpenTween/FilterDialog.en.resx @@ -1,355 +1,86 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - &Close - - - Move - - - - 96, 16 - - - ReTweet Only - - - Copy - - - 122, 16 - - - Lambda expression - - - 75, 16 - - - CaseSens - - - 72, 16 - - - Mark this - - - Cancel - - - 116, 16 - - - Copy from Recent - - - 117, 16 - - - Move from Recent - - - 67, 16 - - - Complex - - - 66, 12 - - - Tweet Body - - - 299, 41 - - - 91, 16 - - - Search &URLs - - - 57, 16 - - - Simple - - - 299, 19 - - - 110, 16 - - - &Regular Express. - - - Create Tab - - - &New - - - Remove Tab - - - 70, 12 - - - Notify sound - - - Rename Tab - - - 73, 16 - - - Protected - - - 61, 12 - - - Kind of tab - - - 104, 16 - - - Manage reading - - - 90, 16 - - - Alert Popups - - - Tabs - - - &Edit - - - &Delete - - - If only the [ExcludingRule] is set, it becomes excluding set to the this tab. - - - 122, 16 - - - Lambda expression - - - 96, 16 - - - ReTweet Only - - - 75, 16 - - - CaseSens - - - 67, 16 - - - Complex - - - 66, 12 - - - Tweet Body - - - 91, 16 - - - Search &URLs - - - 57, 16 - - - Simple - - - 110, 16 - - - &Regular Express. - - - 123, 12 - - - User ID or Tweet Body - - - 44, 12 - - - User ID - - - ExcludingRule - - - 123, 12 - - - User ID or Tweet Body - - - 44, 12 - - - User ID - - - MatchingRule - - - Additional Action (&E): - - - The rules in this tab are applied to all incoming tweet. If the tweet matches the rules, it will be discarded and no longer appear. - - - Rule - - - Distribution Rules - - - Disable - - - Filtering Rules - - \ No newline at end of file + Filtering Rules + Create Tab + Cancel + &Close + &Delete + Remove Tab + &Edit + &New + Rename Tab + Copy + Move + Disable + 75, 16 + CaseSens + 75, 16 + CaseSens + 122, 16 + Lambda expression + 110, 16 + &Regular Express. + 96, 16 + ReTweet Only + 91, 16 + Search &URLs + 122, 16 + Lambda expression + 104, 16 + Manage reading + 72, 16 + Mark this + 90, 16 + Alert Popups + 73, 16 + Protected + 299, 19 + 110, 16 + &Regular Express. + 96, 16 + ReTweet Only + 299, 41 + 91, 16 + Search &URLs + Rule + Additional Action (&E): + Distribution Rules + ExcludingRule + MatchingRule + Tabs + 66, 12 + Tweet Body + 70, 12 + Notify sound + If only the [ExcludingRule] is set, it becomes excluding set to the this tab. + 61, 12 + Kind of tab + 123, 12 + User ID or Tweet Body + 44, 12 + User ID + 44, 12 + User ID + 66, 12 + Tweet Body + 123, 12 + User ID or Tweet Body + The rules in this tab are applied to all incoming tweet. If the tweet matches the rules, it will be discarded and no longer appear. + 116, 16 + Copy from Recent + 117, 16 + Move from Recent + 67, 16 + Complex + 67, 16 + Complex + 57, 16 + Simple + 57, 16 + Simple + diff --git a/OpenTween/FilterDialog.resx b/OpenTween/FilterDialog.resx index bef28edfc..9354e224b 100644 --- a/OpenTween/FilterDialog.resx +++ b/OpenTween/FilterDialog.resx @@ -1,1974 +1,627 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 43, 96 - - - 40, 12 - - - 9 - - - Source - - - Label5 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 2 - - - Bottom, Right - - - 682, 553 - - - 75, 23 - - - 2 - - - 閉じる(&C) - - - ButtonClose - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - 450, 209 - - - 75, 23 - - - 7 - - - 移動 - - - ButtonRuleMove - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 1 - - - True - - - NoControl - - - 299, 84 - - - 84, 16 - - - 14 - - - 公式RTのみ - - - CheckRetweet - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 3 - - - 369, 209 - - - 75, 23 - - - 6 - - - コピー - - - ButtonRuleCopy - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 2 - - - 89, 93 - - - 96, 19 - - - 10 - - - TextSource - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 1 - - - Marlett, 9pt, style=Bold - - - NoControl - - - 131, 209 - - - 34, 23 - - - 3 - - - 6 - - - ButtonRuleDown - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 3 - - - True - - - False - - - NoControl - - - 299, 106 - - - 63, 16 - - - 15 - - - ラムダ式 - - - CheckLambda - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 0 - - - Marlett, 9pt, style=Bold - - - NoControl - - - 90, 209 - - - 34, 23 - - - 2 - - - 5 - - - ButtonRuleUp - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 4 - - - True - - - 299, 62 - - - 102, 16 - - - 13 - - - 大/小文字区別 - - - CheckCaseSensitive - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 4 - - - True - - - 44, 62 - - - 70, 16 - - - 2 - - - マークする - - - CheckMark - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 0 - - - 516, 264 - - - 75, 23 - - - 5 - - - キャンセル - - - ButtonCancel - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EditFilterGroup - - - 4 - - - True - - - 15, 40 - - - 123, 16 - - - 1 - - - Recentからコピーする - - - OptCopy - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 1 - - - True - - - 15, 18 - - - 120, 16 - - - 0 - - - Recentから移動する - - - OptMove - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 2 - - - True - - - 8, 28 - - - 71, 16 - - - 0 - - - 複合条件 - - - RadioAND - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 5 - - - True - - - 187, 14 - - - 53, 12 - - - 4 - - - 発言内容 - - - Label8 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 6 - - - True - - - 299, 40 - - - 70, 16 - - - 12 - - - URL検索 - - - CheckURL - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 7 - - - 438, 264 - - - 75, 23 - - - 4 - - - OK - - - ButtonOK - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EditFilterGroup - - - 5 - - - True - - - 8, 65 - - - 71, 16 - - - 6 - - - 単一条件 - - - RadioPLUS - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 8 - - - True - - - 299, 18 - - - 72, 16 - - - 11 - - - 正規表現 - - - CheckRegex - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 9 - - - True - - - 6, 344 - - - 76, 12 - - - 11 - - - LabelTabType - - - LabelTabType - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 1 - - - 12 - - - 8, 18 - - - 113, 184 - - - 0 - - - ListTabs - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 3 - - - Marlett, 9pt, style=Bold - - - NoControl - - - 87, 207 - - - 34, 23 - - - 2 - - - 6 - - - ButtonDown - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 4 - - - 8, 237 - - - 113, 23 - - - 3 - - - タブ作成 - - - ButtonAddTab - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 5 - - - 9, 209 - - - 75, 23 - - - 1 - - - 新規(&N) - - - ButtonNew - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 8 - - - Marlett, 9pt, style=Bold - - - 8, 207 - - - 34, 23 - - - 1 - - - 5 - - - ButtonUp - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 6 - - - NoControl - - - 8, 266 - - - 113, 23 - - - 4 - - - タブ削除 - - - ButtonDeleteTab - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 7 - - - Bottom, Left - - - True - - - 6, 430 - - - 66, 12 - - - 8 - - - 新着サウンド - - - Label10 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 8 - - - NoControl - - - 8, 295 - - - 113, 23 - - - 5 - - - タブ名変更 - - - ButtonRenameTab - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 9 - - - Bottom, Left - - - True - - - NoControl - - - 8, 367 - - - 65, 16 - - - 6 - - - タブ保護 - - - CheckProtected - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 0 - - - True - - - 6, 327 - - - 56, 12 - - - 10 - - - タブの種類 - - - Label13 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 2 - - - Bottom, Left - - - 8, 445 - - - 113, 20 - - - 9 - - - ComboSound - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 10 - - - Bottom, Left - - - True - - - 8, 389 - - - 72, 16 - - - 7 - - - 未読管理 - - - CheckManageRead - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 11 - - - Bottom, Left - - - True - - - NoControl - - - 8, 411 - - - 96, 16 - - - 8 - - - 新着通知表示 - - - CheckNotifyNew - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupTab - - - 12 - - - 6, 9 - - - 127, 477 - - - 0 - - - タブ - - - GroupTab - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - 173, 209 - - - 75, 23 - - - 4 - - - 編集(&E) - - - ButtonEdit - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 6 - - - 531, 209 - - - 75, 23 - - - 8 - - - 削除(&D) - - - ButtonDelete - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 7 - - - Top, Bottom, Left, Right - - - False - - - NoControl - - - 254, 209 - - - 75, 23 - - - 5 - - - 無効化 - - - buttonRuleToggleEnabled - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 0 - - - True - - - 12 - - - 9, 19 - - - 597, 184 - - - 0 - - - ListFilters - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 5 - - - Top, Bottom, Left, Right - - - 436, 152 - - - 157, 74 - - - 3 - - - 除外ルールのみ設定すると、タブ全体への除外設定となります。 - - - Label11 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EditFilterGroup - - - 0 - - - True - - - False - - - NoControl - - - 299, 106 - - - 63, 16 - - - 15 - - - ラムダ式 - - - CheckExLambDa - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 0 - - - 89, 93 - - - 96, 19 - - - 10 - - - TextExSource - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 1 - - - True - - - NoControl - - - 43, 96 - - - 40, 12 - - - 9 - - - Source - - - Label12 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 2 - - - True - - - NoControl - - - 299, 84 - - - 84, 16 - - - 14 - - - 公式RTのみ - - - CheckExRetweet - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 3 - - - True - - - NoControl - - - 299, 62 - - - 102, 16 - - - 13 - - - 大/小文字区別 - - - CheckExCaseSensitive - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 4 - - - True - - - NoControl - - - 8, 28 - - - 71, 16 - - - 0 - - - 複合条件 - - - RadioExAnd - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 5 - - - True - - - NoControl - - - 187, 14 - - - 53, 12 - - - 4 - - - 発言内容 - - - Label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 6 - - - True - - - NoControl - - - 299, 40 - - - 70, 16 - - - 12 - - - URL検索 - - - CheckExURL - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 7 - - - True - - - NoControl - - - 8, 65 - - - 71, 16 - - - 6 - - - 単一条件 - - - RadioExPLUS - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 8 - - - True - - - NoControl - - - 299, 18 - - - 72, 16 - - - 11 - - - 正規表現 - - - CheckExRegex - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 9 - - - True - - - NoControl - - - 87, 51 - - - 114, 12 - - - 7 - - - ユーザーIDか発言内容 - - - Label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 10 - - - True - - - NoControl - - - 156, 29 - - - 29, 12 - - - 3 - - - AND - - - Label3 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 11 - - - True - - - NoControl - - - 87, 14 - - - 56, 12 - - - 1 - - - ユーザーID - - - Label4 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 12 - - - 89, 26 - - - 61, 19 - - - 2 - - - ExUID - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 13 - - - 189, 26 - - - 103, 19 - - - 5 - - - ExMSG1 - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 14 - - - 89, 64 - - - 204, 19 - - - 8 - - - ExMSG2 - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupExclude - - - 15 - - - 6, 152 - - - 424, 134 - - - 1 - - - 除外ルール - - - GroupExclude - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EditFilterGroup - - - 1 - - - True - - - 87, 51 - - - 114, 12 - - - 7 - - - ユーザーIDか発言内容 - - - Label9 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 10 - - - True - - - 156, 29 - - - 29, 12 - - - 3 - - - AND - - - Label7 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 11 - - - True - - - 87, 14 - - - 56, 12 - - - 1 - - - ユーザーID - - - Label6 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 12 - - - 89, 26 - - - 61, 19 - - - 2 - - - UID - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 13 - - - 189, 26 - - - 103, 19 - - - 5 - - - MSG1 - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 14 - - - 89, 64 - - - 204, 19 - - - 8 - - - MSG2 - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupMatch - - - 15 - - - 6, 18 - - - 424, 128 - - - 0 - - - マッチルール - - - GroupMatch - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EditFilterGroup - - - 2 - - - 436, 18 - - - 155, 98 - - - 2 - - - マッチ時の追加動作(&E) - - - GroupBox1 - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EditFilterGroup - - - 3 - - - Top, Left, Right - - - 436, 18 - - - 158, 128 - - - 6 - - - ミュートタブに設定されたルールは全てのタブの発言に適用されます。マッチした発言は破棄され表示されなくなります。 - - - False - - - labelMuteTab - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EditFilterGroup - - - 6 - - - 9, 238 - - - 600, 293 - - - 9 - - - ルール編集 - - - EditFilterGroup - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 9 - - - 142, 9 - - - 615, 538 - - - 1 - - - 振り分けルール - - - GroupBox2 - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - 39 - - - 96, 96 - - - 769, 583 - - - CenterParent - - - 振り分けルール - - - FilterDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 769, 583 + True + CenterParent + 振り分けルール + 39 + FilterDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + ButtonAddTab + GroupTab + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + ButtonCancel + EditFilterGroup + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + ButtonClose + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + ButtonDelete + GroupBox2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + ButtonDeleteTab + GroupTab + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + ButtonDown + GroupTab + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + ButtonEdit + GroupBox2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + ButtonNew + GroupBox2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + ButtonOK + EditFilterGroup + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + ButtonRenameTab + GroupTab + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + ButtonRuleCopy + GroupBox2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ButtonRuleDown + GroupBox2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + ButtonRuleMove + GroupBox2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + buttonRuleToggleEnabled + GroupBox2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + ButtonRuleUp + GroupBox2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + ButtonUp + GroupTab + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + CheckCaseSensitive + GroupMatch + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + CheckExCaseSensitive + GroupExclude + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + CheckExLambDa + GroupExclude + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + CheckExRegex + GroupExclude + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + CheckExRetweet + GroupExclude + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + CheckExURL + GroupExclude + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + CheckLambda + GroupMatch + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + CheckManageRead + GroupTab + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + CheckMark + GroupBox1 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + CheckNotifyNew + GroupTab + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + CheckProtected + GroupTab + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + CheckRegex + GroupMatch + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + CheckRetweet + GroupMatch + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + CheckURL + GroupMatch + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + ComboSound + GroupTab + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + EditFilterGroup + GroupBox2 + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + ExMSG1 + GroupExclude + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + ExMSG2 + GroupExclude + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + ExUID + GroupExclude + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + GroupBox1 + EditFilterGroup + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + GroupBox2 + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + GroupExclude + EditFilterGroup + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + GroupMatch + EditFilterGroup + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + GroupTab + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + Label1 + GroupExclude + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label10 + GroupTab + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + Label11 + EditFilterGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + Label12 + GroupExclude + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Label13 + GroupTab + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Label2 + GroupExclude + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + Label3 + GroupExclude + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + Label4 + GroupExclude + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + Label5 + GroupMatch + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Label6 + GroupMatch + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + Label7 + GroupMatch + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + Label8 + GroupMatch + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label9 + GroupMatch + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + labelMuteTab + EditFilterGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + LabelTabType + GroupTab + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + ListFilters + GroupBox2 + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + ListTabs + GroupTab + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + MSG1 + GroupMatch + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + MSG2 + GroupMatch + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + OptCopy + GroupBox1 + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + OptMove + GroupBox1 + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + RadioAND + GroupMatch + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + RadioExAnd + GroupExclude + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + RadioExPLUS + GroupExclude + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + RadioPLUS + GroupMatch + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + TextExSource + GroupExclude + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + TextSource + GroupMatch + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + UID + GroupMatch + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + 8, 237 + 113, 23 + 3 + タブ作成 + 516, 264 + 75, 23 + 5 + キャンセル + Bottom, Right + 682, 553 + 75, 23 + 2 + 閉じる(&C) + 531, 209 + 75, 23 + 8 + 削除(&D) + NoControl + 8, 266 + 113, 23 + 4 + タブ削除 + Marlett, 9pt, style=Bold + NoControl + 87, 207 + 34, 23 + 2 + 6 + 173, 209 + 75, 23 + 4 + 編集(&E) + 9, 209 + 75, 23 + 1 + 新規(&N) + 438, 264 + 75, 23 + 4 + OK + NoControl + 8, 295 + 113, 23 + 5 + タブ名変更 + 369, 209 + 75, 23 + 6 + コピー + Marlett, 9pt, style=Bold + NoControl + 131, 209 + 34, 23 + 3 + 6 + 450, 209 + 75, 23 + 7 + 移動 + False + NoControl + 254, 209 + 75, 23 + 5 + 無効化 + Marlett, 9pt, style=Bold + NoControl + 90, 209 + 34, 23 + 2 + 5 + Marlett, 9pt, style=Bold + 8, 207 + 34, 23 + 1 + 5 + True + 299, 62 + 102, 16 + 13 + 大/小文字区別 + True + NoControl + 299, 62 + 102, 16 + 13 + 大/小文字区別 + True + False + NoControl + 299, 106 + 63, 16 + 15 + ラムダ式 + True + NoControl + 299, 18 + 72, 16 + 11 + 正規表現 + True + NoControl + 299, 84 + 84, 16 + 14 + 公式RTのみ + True + NoControl + 299, 40 + 70, 16 + 12 + URL検索 + True + False + NoControl + 299, 106 + 63, 16 + 15 + ラムダ式 + Bottom, Left + True + 8, 389 + 72, 16 + 7 + 未読管理 + True + 44, 62 + 70, 16 + 2 + マークする + Bottom, Left + True + NoControl + 8, 411 + 96, 16 + 8 + 新着通知表示 + Bottom, Left + True + NoControl + 8, 367 + 65, 16 + 6 + タブ保護 + True + 299, 18 + 72, 16 + 11 + 正規表現 + True + NoControl + 299, 84 + 84, 16 + 14 + 公式RTのみ + True + 299, 40 + 70, 16 + 12 + URL検索 + Bottom, Left + 8, 445 + 113, 20 + 9 + Top, Bottom, Left, Right + 9, 238 + 600, 293 + 9 + ルール編集 + 189, 26 + 103, 19 + 5 + 89, 64 + 204, 19 + 8 + 89, 26 + 61, 19 + 2 + 436, 18 + 155, 98 + 2 + マッチ時の追加動作(&E) + Top, Bottom, Left, Right + 142, 9 + 615, 538 + 1 + 振り分けルール + 6, 152 + 424, 134 + 1 + 除外ルール + 6, 18 + 424, 128 + 0 + マッチルール + 6, 9 + 127, 477 + 0 + タブ + True + NoControl + 187, 14 + 53, 12 + 4 + 発言内容 + Bottom, Left + True + 6, 430 + 66, 12 + 8 + 新着サウンド + 436, 152 + 157, 74 + 3 + 除外ルールのみ設定すると、タブ全体への除外設定となります。 + True + NoControl + 43, 96 + 40, 12 + 9 + Source + True + 6, 327 + 56, 12 + 10 + タブの種類 + True + NoControl + 87, 51 + 114, 12 + 7 + ユーザーIDか発言内容 + True + NoControl + 156, 29 + 29, 12 + 3 + AND + True + NoControl + 87, 14 + 56, 12 + 1 + ユーザーID + True + NoControl + 43, 96 + 40, 12 + 9 + Source + True + 87, 14 + 56, 12 + 1 + ユーザーID + True + 156, 29 + 29, 12 + 3 + AND + True + 187, 14 + 53, 12 + 4 + 発言内容 + True + 87, 51 + 114, 12 + 7 + ユーザーIDか発言内容 + Top, Left, Right + 436, 18 + 158, 128 + 6 + ミュートタブに設定されたルールは全てのタブの発言に適用されます。マッチした発言は破棄され表示されなくなります。 + False + True + 6, 344 + 76, 12 + 11 + LabelTabType + True + 12 + 9, 19 + 597, 184 + 0 + 12 + 8, 18 + 113, 184 + 0 + 189, 26 + 103, 19 + 5 + 89, 64 + 204, 19 + 8 + True + 15, 40 + 123, 16 + 1 + Recentからコピーする + True + 15, 18 + 120, 16 + 0 + Recentから移動する + True + 8, 28 + 71, 16 + 0 + 複合条件 + True + NoControl + 8, 28 + 71, 16 + 0 + 複合条件 + True + NoControl + 8, 65 + 71, 16 + 6 + 単一条件 + True + 8, 65 + 71, 16 + 6 + 単一条件 + 89, 93 + 96, 19 + 10 + 89, 93 + 96, 19 + 10 + 89, 26 + 61, 19 + 2 + diff --git a/OpenTween/HashtagManage.en.resx b/OpenTween/HashtagManage.en.resx index 5aca1f78e..5b517535c 100644 --- a/OpenTween/HashtagManage.en.resx +++ b/OpenTween/HashtagManage.en.resx @@ -1,175 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Cancel - - - &Delete - - - &Edit - - - &Add - - - - 86, 12 - - - Using Hash&tags - - - 83, 16 - - - A&lways add - - - Cancel - - - Detail - - - 76, 12 - - - I&nsert Postion - - - 45, 16 - - - Last - - - 49, 16 - - - Head - - - Not &Use - - - &Hashtags - - \ No newline at end of file + &Add + Cancel + 83, 16 + A&lways add + &Delete + &Edit + Detail + &Hashtags + 86, 12 + Using Hash&tags + 76, 12 + I&nsert Postion + Cancel + 49, 16 + Head + 45, 16 + Last + Not &Use + diff --git a/OpenTween/HashtagManage.resx b/OpenTween/HashtagManage.resx index a4d1cee28..a5275e067 100644 --- a/OpenTween/HashtagManage.resx +++ b/OpenTween/HashtagManage.resx @@ -1,753 +1,220 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 12 - - - - 6, 18 - - - 228, 232 - - - 0 - - - HistoryHashList - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 0 - - - True - - - - NoControl - - - 238, 213 - - - 45, 12 - - - 6 - - - 位置(&A) - - - Label3 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 1 - - - NoControl - - - 240, 149 - - - 105, 29 - - - 4 - - - 非使用(&U) - - - UnSelectButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 2 - - - True - - - 293, 228 - - - 47, 16 - - - 8 - - - 文末 - - - RadioLast - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 3 - - - True - - - 240, 228 - - - 47, 16 - - - 7 - - - 文頭 - - - RadioHead - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 5 - - - Bottom, Right - - - 2 - - - Cancel_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutButtons - - - 0 - - - OK_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutButtons - - - 1 - - - 214, 370 - - - 1 - - - 149, 27 - - - 2 - - - TableLayoutButtons - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="Cancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="OK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Absolute,75,AutoSize,0" /><Rows Styles="Percent,100" /></TableLayoutSettings> - - - None - - - NoControl - - - 78, 3 - - - 67, 21 - - - 1 - - - キャンセル - - - Cancel_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutButtons - - - 0 - - - None - - - NoControl - - - 4, 3 - - - 66, 21 - - - 0 - - - OK - - - OK_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutButtons - - - 1 - - - 240, 100 - - - 105, 29 - - - 3 - - - 削除(&D) - - - DeleteButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 4 - - - None - - - NoControl - - - 76, 3 - - - 67, 21 - - - 1 - - - キャンセル - - - PermCancel_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel2 - - - 1 - - - 240, 53 - - - 105, 29 - - - 2 - - - 編集(&E) - - - EditButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 6 - - - NoControl - - - 240, 18 - - - 105, 29 - - - 1 - - - 新規(&N) - - - AddButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 7 - - - CheckPermanent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 8 - - - 12, 3 - - - 351, 255 - - - 0 - - - ハッシュタグ(&H) - - - GroupHashtag - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - 240, 188 - - - 84, 16 - - - 5 - - - 常に付加(&P) - - - CheckPermanent - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupHashtag - - - 8 - - - None - - - NoControl - - - 3, 3 - - - 67, 21 - - - 0 - - - OK - - - PermOK_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel2 - - - 0 - - - Bottom, Right - - - 2 - - - 199, 43 - - - 1 - - - 146, 27 - - - 2 - - - TableLayoutPanel2 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupDetail - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="PermOK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="PermCancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> - - - True - - - 12, 346 - - - 157, 16 - - - 3 - - - @返信の場合は付加しない - - - CheckNotAddToAtReply - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - UseHashText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupDetail - - - 1 - - - Label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupDetail - - - 2 - - - False - - - 12, 264 - - - 351, 76 - - - 1 - - - 詳細 - - - GroupDetail - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - 97, 18 - - - 235, 19 - - - 1 - - - UseHashText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupDetail - - - 1 - - - True - - - 10, 21 - - - 72, 12 - - - 0 - - - ハッシュタグ(&T) - - - Label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupDetail - - - 2 - - - True - - - 96, 96 - - - 375, 409 - - - CenterParent - - - HashtagManage - - - HashtagManage - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 375, 409 + True + CenterParent + HashtagManage + HashtagManage + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + AddButton + GroupHashtag + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + Cancel_Button + Cancel_Button + TableLayoutButtons + TableLayoutButtons + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + 0 + CheckNotAddToAtReply + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + CheckPermanent + CheckPermanent + GroupHashtag + GroupHashtag + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + 8 + DeleteButton + GroupHashtag + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + EditButton + GroupHashtag + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + GroupDetail + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + GroupHashtag + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + HistoryHashList + GroupHashtag + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + Label1 + Label1 + GroupDetail + GroupDetail + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + 2 + Label3 + GroupHashtag + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + OK_Button + OK_Button + TableLayoutButtons + TableLayoutButtons + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + 1 + PermCancel_Button + TableLayoutPanel2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + PermOK_Button + TableLayoutPanel2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + RadioHead + GroupHashtag + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + RadioLast + GroupHashtag + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + TableLayoutButtons + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TableLayoutPanel2 + GroupDetail + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + UnSelectButton + GroupHashtag + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + UseHashText + UseHashText + GroupDetail + GroupDetail + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + 1 + NoControl + 240, 18 + 105, 29 + 1 + 新規(&N) + None + NoControl + 78, 3 + 67, 21 + 1 + キャンセル + True + 12, 346 + 157, 16 + 3 + @返信の場合は付加しない + True + 240, 188 + 84, 16 + 5 + 常に付加(&P) + 240, 100 + 105, 29 + 3 + 削除(&D) + 240, 53 + 105, 29 + 2 + 編集(&E) + False + 12, 264 + 351, 76 + 1 + 詳細 + 12, 3 + 351, 255 + 0 + ハッシュタグ(&H) + 12 + 6, 18 + 228, 232 + 0 + True + 10, 21 + 72, 12 + 0 + ハッシュタグ(&T) + True + NoControl + 238, 213 + 45, 12 + 6 + 位置(&A) + None + NoControl + 4, 3 + 66, 21 + 0 + OK + None + NoControl + 76, 3 + 67, 21 + 1 + キャンセル + None + NoControl + 3, 3 + 67, 21 + 0 + OK + True + 240, 228 + 47, 16 + 7 + 文頭 + True + 293, 228 + 47, 16 + 8 + 文末 + Bottom, Right + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="Cancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="OK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Absolute,75,AutoSize,0" /><Rows Styles="Percent,100" /></TableLayoutSettings> + 214, 370 + 1 + 149, 27 + 2 + Bottom, Right + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="PermOK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="PermCancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> + 199, 43 + 1 + 146, 27 + 2 + NoControl + 240, 149 + 105, 29 + 4 + 非使用(&U) + 97, 18 + 235, 19 + 1 + diff --git a/OpenTween/InputDialog.en.resx b/OpenTween/InputDialog.en.resx index b22657b2f..9d3cd531d 100644 --- a/OpenTween/InputDialog.en.resx +++ b/OpenTween/InputDialog.en.resx @@ -1,123 +1,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - &Cancel - - \ No newline at end of file + &Cancel + diff --git a/OpenTween/InputDialog.resx b/OpenTween/InputDialog.resx index d315e74da..ab1dbd0f7 100644 --- a/OpenTween/InputDialog.resx +++ b/OpenTween/InputDialog.resx @@ -1,306 +1,71 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 3, 3 - - - 78, 23 - - - 0 - - - &OK - - - buttonOK - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 0 - - - True - - - NoControl - - - 87, 3 - - - 78, 23 - - - 1 - - - キャンセル(&C) - - - buttonCancel - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 1 - - - Bottom, Right - - - True - - - 2 - - - 219, 63 - - - 1 - - - 168, 29 - - - 2 - - - tableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="buttonOK" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonCancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0" /></TableLayoutSettings> - - - Top, Left, Right - - - 16, 36 - - - 5, 5, 5, 5 - - - 369, 19 - - - 1 - - - textBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - NoControl - - - 14, 14 - - - 5, 5, 5, 5 - - - 35, 12 - - - 0 - - - label1 - - - labelMain - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - 96, 96 - - - True - - - 399, 104 - - - NoControl - - - CenterParent - - - InputDialog - - - InputDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + 399, 104 + NoControl + True + CenterParent + InputDialog + InputDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + buttonCancel + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + buttonOK + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + labelMain + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + tableLayoutPanel1 + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + textBox + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + True + NoControl + 87, 3 + 78, 23 + 1 + キャンセル(&C) + True + NoControl + 3, 3 + 78, 23 + 0 + &OK + True + NoControl + 14, 14 + 5, 5, 5, 5 + 35, 12 + 0 + label1 + Bottom, Right + True + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="buttonOK" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonCancel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0" /></TableLayoutSettings> + 219, 63 + 1 + 168, 29 + 2 + Top, Left, Right + 16, 36 + 5, 5, 5, 5 + 369, 19 + 1 + diff --git a/OpenTween/InputTabName.en.resx b/OpenTween/InputTabName.en.resx index e5174f488..f5a2bf445 100644 --- a/OpenTween/InputTabName.en.resx +++ b/OpenTween/InputTabName.en.resx @@ -1,139 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Cancel - - - - 81, 12 - - - Input tab name - - - 50, 12 - - - Tab type - - - Input Tab Name - - \ No newline at end of file + Input Tab Name + Cancel + 81, 12 + Input tab name + 50, 12 + Tab type + diff --git a/OpenTween/InputTabName.resx b/OpenTween/InputTabName.resx index 306a91264..4cd453281 100644 --- a/OpenTween/InputTabName.resx +++ b/OpenTween/InputTabName.resx @@ -1,330 +1,79 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - 67, 21 - - - OK_Button - - - キャンセル - - - $this - - - ComboUsage - - - - NoControl - - - TableLayoutPanel1 - - - 1 - - - 67, 21 - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 1 - - - 146, 27 - - - 12, 24 - - - 257, 19 - - - 3 - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - None - - - 148, 12 - - - None - - - 12, 9 - - - 12, 46 - - - True - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - Cancel_Button - - - Bottom, Right - - - OK - - - 76, 3 - - - 1 - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - $this - - - $this - - - 1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - タブの名前を入力してください。 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - タブ種類 - - - 280, 130 - - - 12, 61 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="OK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="Cancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> - - - 1 - - - 0 - - - 257, 20 - - - 2 - - - LabelDescription - - - TextTabName - - - 46, 12 - - - 2 - - - タブ名入力 - - - 0 - - - TableLayoutPanel1 - - - $this - - - CenterParent - - - 2 - - - 0 - - - 96, 96 - - - 3 - - - TableLayoutPanel1 - - - 0 - - - 4 - - - InputTabName - - - 3, 3 - - - 122, 92 - - - 4 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - LabelUsage - - - True - - \ No newline at end of file + 96, 96 + 280, 130 + True + CenterParent + タブ名入力 + InputTabName + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + Cancel_Button + TableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + ComboUsage + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + LabelDescription + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + LabelUsage + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + OK_Button + TableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TableLayoutPanel1 + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + TextTabName + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + None + 76, 3 + 67, 21 + 1 + キャンセル + 12, 61 + 257, 20 + 3 + True + 12, 9 + 148, 12 + 0 + タブの名前を入力してください。 + True + NoControl + 12, 46 + 46, 12 + 2 + タブ種類 + None + 3, 3 + 67, 21 + 0 + OK + Bottom, Right + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="OK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="Cancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> + 122, 92 + 1 + 146, 27 + 4 + 12, 24 + 257, 19 + 1 + diff --git a/OpenTween/ListAvailable.en.resx b/OpenTween/ListAvailable.en.resx index cf5edb5bc..071d13648 100644 --- a/OpenTween/ListAvailable.en.resx +++ b/OpenTween/ListAvailable.en.resx @@ -1,160 +1,21 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Cancel - - - - 37, 12 - - - Owner - - - 24, 12 - - - List - - - 63, 12 - - - Description - - - 38, 12 - - - Status - - - 51, 12 - - - Members - - - 65, 12 - - - Subscribers - - \ No newline at end of file + Cancel + 37, 12 + Owner + 51, 12 + Members + 65, 12 + Subscribers + 24, 12 + List + 63, 12 + Description + 38, 12 + Status + diff --git a/OpenTween/ListAvailable.resx b/OpenTween/ListAvailable.resx index 4a35353b9..69d9544b4 100644 --- a/OpenTween/ListAvailable.resx +++ b/OpenTween/ListAvailable.resx @@ -1,621 +1,176 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 12 - - - - 12, 12 - - - 284, 232 - - - 0 - - - ListsList - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - - None - - - 12, 256 - - - 67, 21 - - - 2 - - - Refresh - - - RefreshButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - 318, 159 - - - True - - - 174, 88 - - - 14 - - - Description - - - DescriptionText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - 318, 130 - - - 46, 14 - - - 12 - - - Label11 - - - TopRight - - - SubscriberCountLabel - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - 302, 118 - - - 53, 12 - - - 11 - - - 購読者数 - - - Label12 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - 318, 102 - - - 46, 14 - - - 10 - - - Label9 - - - TopRight - - - MemberCountLabel - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - 302, 90 - - - 53, 12 - - - 9 - - - 登録者数 - - - Label10 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - 318, 76 - - - 174, 14 - - - 8 - - - Label7 - - - StatusLabel - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - True - - - 302, 64 - - - 29, 12 - - - 7 - - - 種別 - - - Label8 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - True - - - 302, 144 - - - 29, 12 - - - 13 - - - 説明 - - - Label6 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - 318, 50 - - - 174, 14 - - - 6 - - - Label3 - - - NameLabel - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - True - - - 302, 38 - - - 41, 12 - - - 5 - - - リスト名 - - - Label4 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - 318, 24 - - - 174, 14 - - - 4 - - - Label2 - - - UsernameLabel - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 12 - - - True - - - 302, 12 - - - 41, 12 - - - 3 - - - 作成者 - - - Label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 13 - - - Bottom, Right - - - 2 - - - OK_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 0 - - - Cancel_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 1 - - - 346, 253 - - - 1 - - - 146, 27 - - - 1 - - - TableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 14 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="OK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="Cancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> - - - None - - - 3, 3 - - - 67, 21 - - - 0 - - - OK - - - OK_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 0 - - - None - - - 76, 3 - - - 67, 21 - - - 1 - - - キャンセル - - - Cancel_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 1 - - - True - - - 96, 96 - - - 504, 291 - - - CenterParent - - - ListAvailable - - - ListAvailable - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 504, 291 + True + CenterParent + ListAvailable + ListAvailable + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + Cancel_Button + Cancel_Button + TableLayoutPanel1 + TableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + 1 + DescriptionText + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Label1 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + Label10 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label12 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + Label4 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + Label6 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + Label8 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + ListsList + $this + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + MemberCountLabel + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + NameLabel + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + OK_Button + OK_Button + TableLayoutPanel1 + TableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + 0 + RefreshButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + StatusLabel + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + SubscriberCountLabel + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + TableLayoutPanel1 + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + UsernameLabel + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + None + 76, 3 + 67, 21 + 1 + キャンセル + 318, 159 + True + 174, 88 + 14 + Description + True + 302, 12 + 41, 12 + 3 + 作成者 + True + 302, 90 + 53, 12 + 9 + 登録者数 + True + 302, 118 + 53, 12 + 11 + 購読者数 + True + 302, 38 + 41, 12 + 5 + リスト名 + True + 302, 144 + 29, 12 + 13 + 説明 + True + 302, 64 + 29, 12 + 7 + 種別 + 12 + 12, 12 + 284, 232 + 0 + 318, 102 + 46, 14 + 10 + Label9 + TopRight + 318, 50 + 174, 14 + 6 + Label3 + None + 3, 3 + 67, 21 + 0 + OK + None + 12, 256 + 67, 21 + 2 + Refresh + 318, 76 + 174, 14 + 8 + Label7 + 318, 130 + 46, 14 + 12 + Label11 + TopRight + Bottom, Right + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="OK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="Cancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> + 346, 253 + 1 + 146, 27 + 1 + 318, 24 + 174, 14 + 4 + Label2 + diff --git a/OpenTween/ListManage.en.resx b/OpenTween/ListManage.en.resx index a46ccf2cd..c2455c81a 100644 --- a/OpenTween/ListManage.en.resx +++ b/OpenTween/ListManage.en.resx @@ -1,229 +1,44 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 65, 12 - - - Subscribers - - - 51, 12 - - - Members - - - 63, 12 - - - Description - - - 34, 12 - - - Name - - - 37, 12 - - - Owner - - - 68, 12 - - - LatestTweet - - - Remove from &List - - - 22, 12 - - - Bio - - - 50, 12 - - - Statuses - - - 48, 12 - - - Follower - - - 38, 12 - - - Follow - - - 48, 12 - - - Location - - - User - - - &Add - - - &Delete - - - &More - - - &Edit - - - Kind - - - Detail - - - Refresh(&U) - - - &Refresh - - - 30, 12 - - - Lists - - - &Close - - - Members - - \ No newline at end of file + &Add + &Close + &Delete + Remove from &List + &Edit + &More + Kind + 37, 12 + Owner + 51, 12 + Members + 65, 12 + Subscribers + 48, 12 + Follower + 50, 12 + Statuses + 22, 12 + Bio + 68, 12 + LatestTweet + 30, 12 + Lists + 34, 12 + Name + 48, 12 + Location + 63, 12 + Description + 38, 12 + Follow + Detail + Members + &Refresh + Refresh(&U) + User + diff --git a/OpenTween/ListManage.resx b/OpenTween/ListManage.resx index 467e1a521..17cb49b93 100644 --- a/OpenTween/ListManage.resx +++ b/OpenTween/ListManage.resx @@ -1,1473 +1,460 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 90, 293 - - - 112, 12 - - - - 12 - - - YY/MM/DD HH:MM - - - TopRight - - - UserTweetDateTime - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 0 - - - 11, 19 - - - 49, 49 - - - - Zoom - - - 37 - - - UserIcon - - - OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - UserGroup - - - 1 - - - Disable - - - 12 - - - 12, 24 - - - 215, 184 - - - 1 - - - ListsList - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - 11, 305 - - - 191, 135 - - - 14 - - - Label19 - - - UserTweet - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 2 - - - 9, 443 - - - 193, 23 - - - 15 - - - リストから削除(&L) - - - DeleteUserButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 4 - - - 11, 155 - - - 191, 135 - - - 11 - - - Label18 - - - UserProfile - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 5 - - - True - - - False - - - 38, 9 - - - 59, 16 - - - 0 - - - Private - - - PrivateRadioButton - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 0 - - - PublicRadioButton - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 1 - - - 8, 68 - - - 197, 29 - - - 4 - - - 種別 - - - GroupBox2 - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 2 - - - True - - - False - - - 103, 9 - - - 54, 16 - - - 1 - - - Public - - - PublicRadioButton - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox2 - - - 1 - - - Button - - - 71, 214 - - - 53, 23 - - - 3 - - - 編集(&E) - - - MiddleCenter - - - EditCheckBox - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - 9, 293 - - - 75, 12 - - - 13 - - - 最近のツイート - - - Label20 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 3 - - - 75, 128 - - - 46, 19 - - - 8 - - - SubscriberCountTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 4 - - - 75, 103 - - - 46, 19 - - - 6 - - - MemberCountTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 5 - - - 65, 18 - - - 140, 19 - - - 1 - - - UsernameTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 6 - - - True - - - 9, 143 - - - 53, 12 - - - 10 - - - 自己紹介 - - - Label17 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 6 - - - 12, 243 - - - 215, 23 - - - 5 - - - 再取得(&R) - - - RefreshListsButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - 147, 125 - - - 55, 14 - - - 9 - - - Label16 - - - TopRight - - - UserPostsNum - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 7 - - - True - - - 10, 9 - - - 29, 12 - - - 0 - - - リスト - - - Label3 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - 147, 109 - - - 41, 12 - - - 8 - - - 発言数 - - - Label15 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 8 - - - NoControl - - - 596, 490 - - - 75, 23 - - - 9 - - - 閉じる(&C) - - - CloseButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - 77, 109 - - - 49, 12 - - - 6 - - - フォロワー - - - Label13 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 10 - - - 141, 472 - - - 77, 23 - - - 2 - - - 再取得(&U) - - - RefreshUsersButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MemberGroup - - - 2 - - - 79, 125 - - - 55, 14 - - - 7 - - - Label14 - - - TopRight - - - UserFollowerNum - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 9 - - - Label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 0 - - - CancelEditButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 1 - - - OKEditButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 3 - - - NameTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 7 - - - Label4 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 8 - - - Label6 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 9 - - - Label10 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 10 - - - DescriptionText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 11 - - - Label12 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 12 - - - 12, 269 - - - 215, 241 - - - 6 - - - 詳細 - - - ListGroup - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 6, 21 - - - 41, 12 - - - 0 - - - 作成者 - - - Label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 0 - - - False - - - 111, 213 - - - 75, 23 - - - 12 - - - Cancel - - - CancelEditButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 1 - - - False - - - 16, 213 - - - 75, 23 - - - 11 - - - OK - - - OKEditButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 3 - - - 65, 43 - - - 140, 19 - - - 3 - - - NameTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 7 - - - True - - - NoControl - - - 6, 46 - - - 41, 12 - - - 2 - - - リスト名 - - - Label4 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 8 - - - True - - - NoControl - - - 6, 156 - - - 29, 12 - - - 9 - - - 説明 - - - Label6 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 9 - - - True - - - NoControl - - - 6, 106 - - - 53, 12 - - - 5 - - - 登録者数 - - - Label10 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 10 - - - 75, 153 - - - True - - - 130, 56 - - - 10 - - - Description - - - DescriptionText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 11 - - - True - - - NoControl - - - 6, 131 - - - 53, 12 - - - 7 - - - 購読者数 - - - Label12 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListGroup - - - 12 - - - 11, 125 - - - 55, 14 - - - 5 - - - Label11 - - - TopRight - - - UserFollowNum - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 11 - - - True - - - 9, 109 - - - 40, 12 - - - 4 - - - フォロー - - - Label9 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 12 - - - UserList - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MemberGroup - - - 0 - - - GetMoreUsersButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MemberGroup - - - 1 - - - 233, 9 - - - 224, 501 - - - 7 - - - メンバー - - - MemberGroup - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - Disable - - - 12 - - - 6, 15 - - - 212, 424 - - - 0 - - - UserList - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MemberGroup - - - 0 - - - 6, 445 - - - 212, 23 - - - 1 - - - 取得(&M) - - - GetMoreUsersButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MemberGroup - - - 1 - - - 12, 214 - - - 53, 23 - - - 2 - - - 追加(&A) - - - AddListButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - 174, 214 - - - 53, 23 - - - 4 - - - 削除(&D) - - - DeleteListButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - 41, 72 - - - 161, 35 - - - 3 - - - LinkLabel1 - - - UserWeb - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 13 - - - 68, 31 - - - 134, 37 - - - 1 - - - Label7 - - - UserLocation - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 15 - - - True - - - 9, 74 - - - 26, 12 - - - 2 - - - Web - - - Label8 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 14 - - - Label5 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 16 - - - 463, 9 - - - 208, 475 - - - 8 - - - ユーザー情報 - - - UserGroup - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - True - - - 66, 19 - - - 41, 12 - - - 0 - - - 現在地 - - - Label5 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserGroup - - - 16 - - - True - - - 96, 96 - - - 683, 522 - - - CenterParent - - - ListManage - - - ListManage - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 683, 522 + True + CenterParent + ListManage + ListManage + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + AddListButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + CancelEditButton + CancelEditButton + ListGroup + ListGroup + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + 1 + CloseButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + DeleteListButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + DeleteUserButton + UserGroup + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + DescriptionText + DescriptionText + ListGroup + ListGroup + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + 11 + EditCheckBox + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + GetMoreUsersButton + GetMoreUsersButton + MemberGroup + MemberGroup + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + 1 + GroupBox2 + ListGroup + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Label1 + Label1 + ListGroup + ListGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + 0 + Label10 + Label10 + ListGroup + ListGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + 10 + Label12 + Label12 + ListGroup + ListGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + 12 + Label13 + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + Label15 + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + Label17 + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label20 + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + Label3 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + Label4 + Label4 + ListGroup + ListGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + 8 + Label5 + Label5 + UserGroup + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 16 + 16 + Label6 + Label6 + ListGroup + ListGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + 9 + Label8 + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + Label9 + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + ListGroup + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + ListsList + $this + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + MemberCountTextBox + ListGroup + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + MemberGroup + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + NameTextBox + NameTextBox + ListGroup + ListGroup + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + 7 + OKEditButton + OKEditButton + ListGroup + ListGroup + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + 3 + PrivateRadioButton + GroupBox2 + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + PublicRadioButton + PublicRadioButton + GroupBox2 + GroupBox2 + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + 1 + RefreshListsButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + RefreshUsersButton + MemberGroup + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + SubscriberCountTextBox + ListGroup + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + UserFollowerNum + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + UserFollowNum + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + UserGroup + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + UserIcon + UserGroup + OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 1 + UserList + UserList + MemberGroup + MemberGroup + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + 0 + UserLocation + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + UsernameTextBox + ListGroup + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + UserPostsNum + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + UserProfile + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + UserTweet + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + UserTweetDateTime + UserGroup + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + UserWeb + UserGroup + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + 12, 214 + 53, 23 + 2 + 追加(&A) + False + 111, 213 + 75, 23 + 12 + Cancel + NoControl + 596, 490 + 75, 23 + 9 + 閉じる(&C) + 174, 214 + 53, 23 + 4 + 削除(&D) + 9, 443 + 193, 23 + 15 + リストから削除(&L) + 75, 153 + True + 130, 56 + 10 + Description + Button + 71, 214 + 53, 23 + 3 + 編集(&E) + MiddleCenter + 6, 445 + 212, 23 + 1 + 取得(&M) + 8, 68 + 197, 29 + 4 + 種別 + True + NoControl + 6, 21 + 41, 12 + 0 + 作成者 + True + NoControl + 6, 106 + 53, 12 + 5 + 登録者数 + True + NoControl + 6, 131 + 53, 12 + 7 + 購読者数 + True + 77, 109 + 49, 12 + 6 + フォロワー + True + 147, 109 + 41, 12 + 8 + 発言数 + True + 9, 143 + 53, 12 + 10 + 自己紹介 + True + 9, 293 + 75, 12 + 13 + 最近のツイート + True + 10, 9 + 29, 12 + 0 + リスト + True + NoControl + 6, 46 + 41, 12 + 2 + リスト名 + True + 66, 19 + 41, 12 + 0 + 現在地 + True + NoControl + 6, 156 + 29, 12 + 9 + 説明 + True + 9, 74 + 26, 12 + 2 + Web + True + 9, 109 + 40, 12 + 4 + フォロー + 12, 269 + 215, 241 + 6 + 詳細 + Disable + 12 + 12, 24 + 215, 184 + 1 + 75, 103 + 46, 19 + 6 + 233, 9 + 224, 501 + 7 + メンバー + 65, 43 + 140, 19 + 3 + False + 16, 213 + 75, 23 + 11 + OK + True + False + 38, 9 + 59, 16 + 0 + Private + True + False + 103, 9 + 54, 16 + 1 + Public + 12, 243 + 215, 23 + 5 + 再取得(&R) + 141, 472 + 77, 23 + 2 + 再取得(&U) + 75, 128 + 46, 19 + 8 + 79, 125 + 55, 14 + 7 + Label14 + TopRight + 11, 125 + 55, 14 + 5 + Label11 + TopRight + 463, 9 + 208, 475 + 8 + ユーザー情報 + 11, 19 + 49, 49 + Zoom + 37 + True + Disable + 12 + 6, 15 + 212, 424 + 0 + 68, 31 + 134, 37 + 1 + Label7 + 65, 18 + 140, 19 + 1 + 147, 125 + 55, 14 + 9 + Label16 + TopRight + 11, 155 + 191, 135 + 11 + Label18 + 11, 305 + 191, 135 + 14 + Label19 + 90, 293 + 112, 12 + 12 + YY/MM/DD HH:MM + TopRight + 41, 72 + 161, 35 + 3 + LinkLabel1 + diff --git a/OpenTween/LoginDialog.en.resx b/OpenTween/LoginDialog.en.resx index 61d4b70b1..8685a0b41 100644 --- a/OpenTween/LoginDialog.en.resx +++ b/OpenTween/LoginDialog.en.resx @@ -1,139 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 56, 12 - - - &Username - - - 54, 12 - - - &Password - - - &Login - - - &Cancel - - \ No newline at end of file + &Cancel + &Login + 56, 12 + &Username + 54, 12 + &Password + diff --git a/OpenTween/LoginDialog.resx b/OpenTween/LoginDialog.resx index 696d377d9..e7b011fcc 100644 --- a/OpenTween/LoginDialog.resx +++ b/OpenTween/LoginDialog.resx @@ -1,306 +1,71 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - 12, 15 - - - 73, 12 - - - 0 - - - ユーザー名(&U) - - - label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - - Top, Left, Right - - - 94, 12 - - - 193, 19 - - - 1 - - - textboxLoginName - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - 12, 40 - - - 67, 12 - - - 2 - - - パスワード(&P) - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - Top, Left, Right - - - 94, 37 - - - 193, 19 - - - 3 - - - textboxPassword - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Bottom, Right - - - True - - - 146, 64 - - - 75, 25 - - - 4 - - - ログイン(&L) - - - buttonLogin - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Bottom, Right - - - True - - - 227, 64 - - - 78, 25 - - - 5 - - - キャンセル(&C) - - - buttonCancel - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 6, 12 - - - 317, 101 - - - CenterParent - - - LoginDialog - - - LoginDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 6, 12 + 317, 101 + True + CenterParent + LoginDialog + LoginDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + buttonCancel + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + buttonLogin + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + label1 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + label2 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + textboxLoginName + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + textboxPassword + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Bottom, Right + True + 227, 64 + 78, 25 + 5 + キャンセル(&C) + Bottom, Right + True + 146, 64 + 75, 25 + 4 + ログイン(&L) + True + 12, 15 + 73, 12 + 0 + ユーザー名(&U) + True + 12, 40 + 67, 12 + 2 + パスワード(&P) + Top, Left, Right + 94, 12 + 193, 19 + 1 + Top, Left, Right + 94, 37 + 193, 19 + 3 + diff --git a/OpenTween/MediaSelector.en.resx b/OpenTween/MediaSelector.en.resx index fd51a0b36..526c1d59d 100644 --- a/OpenTween/MediaSelector.en.resx +++ b/OpenTween/MediaSelector.en.resx @@ -1,126 +1,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Service - - - &Alternative text: - - \ No newline at end of file + &Alternative text: + Service + diff --git a/OpenTween/MediaSelector.resx b/OpenTween/MediaSelector.resx index c73deade5..5f2bbbc17 100644 --- a/OpenTween/MediaSelector.resx +++ b/OpenTween/MediaSelector.resx @@ -1,450 +1,119 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Fill - - - - 61, 3 - - - 297, 19 - - - - 1 - - - ImagefilePathText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ImagePathPanel - - - 0 - - - Left - - - 3, 3 - - - 58, 20 - - - 0 - - - ImagePageCombo - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ImagePathPanel - - - 1 - - - Right - - - NoControl - - - 358, 3 - - - 23, 22 - - - 2 - - - ... - - - FilePickButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ImagePathPanel - - - 2 - - - Right - - - NoControl - - - 381, 3 - - - 61, 22 - - - 3 - - - 投稿先 - - - MiddleRight - - - Label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ImagePathPanel - - - 3 - - - Right - - - Twitter - - - 442, 3 - - - 103, 20 - - - 4 - - - ImageServiceCombo - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ImagePathPanel - - - 4 - - - Right - - - NoControl - - - 545, 3 - - - 60, 22 - - - 5 - - - Cancel - - - ImageCancelButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ImagePathPanel - - - 5 - - - Bottom - - - 0, 252 - - - 3, 3, 3, 3 - - - 608, 28 - - - 0 - - - ImagePathPanel - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - Top, Left, Right - - - 109, 3 - - - 496, 19 - - - 1 - - - AlternativeTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - AlternativeTextPanel - - - 0 - - - Top, Bottom, Left - - - NoControl - - - 3, 3 - - - 100, 19 - - - 0 - - - 代替テキスト(&A): - - - MiddleRight - - - AlternativeTextLabel - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - AlternativeTextPanel - - - 1 - - - Bottom - - - 0, 227 - - - 608, 25 - - - 2 - - - False - - - AlternativeTextPanel - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Fill - - - NoControl - - - 0, 0 - - - 608, 227 - - - Zoom - - - 0 - - - ImageSelectedPicture - - - OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - $this - - - 0 - - - True - - - 96, 96 - - - 608, 280 - - - MediaSelector - - - System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file + 96, 96 + True + 608, 280 + MediaSelector + System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AlternativeTextBox + AlternativeTextPanel + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + AlternativeTextLabel + AlternativeTextPanel + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + AlternativeTextPanel + $this + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + FilePickButton + ImagePathPanel + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ImageCancelButton + ImagePathPanel + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + ImagefilePathText + ImagePathPanel + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + ImagePageCombo + ImagePathPanel + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + ImagePathPanel + $this + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ImageSelectedPicture + $this + OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 0 + ImageServiceCombo + ImagePathPanel + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + Label2 + ImagePathPanel + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + Top, Left, Right + 109, 3 + 496, 19 + 1 + Top, Bottom, Left + NoControl + 3, 3 + 100, 19 + 0 + 代替テキスト(&A): + MiddleRight + True + Bottom + 0, 227 + 608, 25 + 2 + False + Right + NoControl + 358, 3 + 23, 22 + 2 + ... + Right + NoControl + 545, 3 + 60, 22 + 5 + Cancel + Fill + 61, 3 + 297, 19 + 1 + Left + 3, 3 + 58, 20 + 0 + Bottom + 0, 252 + 3, 3, 3, 3 + 608, 28 + 0 + Fill + NoControl + 0, 0 + 608, 227 + Zoom + 0 + Right + Twitter + 442, 3 + 103, 20 + 4 + Right + NoControl + 381, 3 + 61, 22 + 3 + 投稿先 + MiddleRight + diff --git a/OpenTween/MyLists.en.resx b/OpenTween/MyLists.en.resx index d484c0ab0..cb9cf86d2 100644 --- a/OpenTween/MyLists.en.resx +++ b/OpenTween/MyLists.en.resx @@ -1,136 +1,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 79, 22 - - - &Reload Lists - - - 184, 179 - - - 44, 22 - - - &Close - - \ No newline at end of file + 184, 179 + 44, 22 + &Close + 79, 22 + &Reload Lists + diff --git a/OpenTween/MyLists.resx b/OpenTween/MyLists.resx index c96f57c4a..78a9be858 100644 --- a/OpenTween/MyLists.resx +++ b/OpenTween/MyLists.resx @@ -1,297 +1,68 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Top, Bottom, Left, Right - - - 17, 17 - - - - 152, 22 - - - 追加(&A) - - - 152, 22 - - - 削除(&D) - - - 149, 6 - - - 152, 22 - - - 更新(&R) - - - 111, 76 - - - ContextMenuStrip1 - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - False - - - 0, 0 - - - 228, 177 - - - 0 - - - ListsCheckedListBox - - - System.Windows.Forms.CheckedListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - Bottom, Left - - - True - - - GrowAndShrink - - - 0, 179 - - - 112, 22 - - - 1 - - - リスト一覧を更新(&R) - - - ListRefreshButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Bottom, Right - - - True - - - GrowAndShrink - - - 167, 179 - - - 61, 22 - - - 2 - - - 閉じる(&C) - - - CloseButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - 96, 96 - - - 228, 201 - - - CenterParent - - - MyLists - - - MenuItemAdd - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemDelete - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripMenuItem1 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemReload - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MyLists - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 228, 201 + True + CenterParent + MyLists + MyLists + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + CloseButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + ContextMenuStrip1 + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ListRefreshButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ListsCheckedListBox + $this + System.Windows.Forms.CheckedListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + MenuItemAdd + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemDelete + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemReload + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripMenuItem1 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + Bottom, Right + True + GrowAndShrink + 167, 179 + 61, 22 + 2 + 閉じる(&C) + 111, 76 + 17, 17 + Bottom, Left + True + GrowAndShrink + 0, 179 + 112, 22 + 1 + リスト一覧を更新(&R) + Top, Bottom, Left, Right + True + False + 0, 0 + 228, 177 + 0 + 152, 22 + 追加(&A) + 152, 22 + 削除(&D) + 152, 22 + 更新(&R) + 149, 6 + diff --git a/OpenTween/OpenURL.en.resx b/OpenTween/OpenURL.en.resx index 57d2bdf89..17d2274e3 100644 --- a/OpenTween/OpenURL.en.resx +++ b/OpenTween/OpenURL.en.resx @@ -1,123 +1,8 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Cancel - - \ No newline at end of file + Cancel + diff --git a/OpenTween/OpenURL.resx b/OpenTween/OpenURL.resx index 5ce22c094..73765a39c 100644 --- a/OpenTween/OpenURL.resx +++ b/OpenTween/OpenURL.resx @@ -1,312 +1,73 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - None - - - - 3, 3 - - - 67, 21 - - - - 0 - - - OK - - - OK_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 0 - - - 1 - - - Bottom, Right - - - 2 - - - Cancel_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 1 - - - 275, 164 - - - 1 - - - 146, 27 - - - 1 - - - TableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel2 - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="OK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="Cancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> - - - Fill - - - Disable - - - 12 - - - 3, 3 - - - 418, 148 - - - 0 - - - UrlList - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel2 - - - 1 - - - Fill - - - 0, 0 - - - 2 - - - 424, 194 - - - 0 - - - TableLayoutPanel2 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="TableLayoutPanel1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="UrlList" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,Absolute,40" /></TableLayoutSettings> - - - None - - - 76, 3 - - - 67, 21 - - - 1 - - - キャンセル - - - Cancel_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 1 - - - True - - - 96, 96 - - - 424, 194 - - - Disable - - - 150, 200 - - - CenterParent - - - OpenURL - - - OpenURL - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 424, 194 + Disable + True + 150, 200 + CenterParent + OpenURL + OpenURL + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + Cancel_Button + Cancel_Button + TableLayoutPanel1 + TableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + 1 + OK_Button + TableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TableLayoutPanel1 + TableLayoutPanel2 + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TableLayoutPanel2 + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + UrlList + TableLayoutPanel2 + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + None + 76, 3 + 67, 21 + 1 + キャンセル + None + 3, 3 + 67, 21 + 0 + OK + Bottom, Right + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="OK_Button" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="Cancel_Button" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> + 275, 164 + 1 + 146, 27 + 1 + 1 + Fill + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="TableLayoutPanel1" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="UrlList" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,Absolute,40" /></TableLayoutSettings> + 0, 0 + 2 + 424, 194 + 0 + Fill + Disable + 12 + 3, 3 + 418, 148 + 0 + diff --git a/OpenTween/Properties/Resources.en.resx b/OpenTween/Properties/Resources.en.resx index 3a90bbc42..c955aab6e 100644 --- a/OpenTween/Properties/Resources.en.resx +++ b/OpenTween/Properties/Resources.en.resx @@ -1,1129 +1,360 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - (New Tab) - - - Name - - - Post - - - Date - - - Username - - - Tab ""{0}"" is already exists; please specify other name. - - - Add tab - - - Executable (*.exe)|*.exe|All files (*.*)|*.* - - - Choose the web browser - - - Delete this rules? {0} 『{1}』 - - - Confirm deleting rule - - - Choice the rule. - - - Rule checking - - - Invalid regular expression pattern. - - - %AppName% Update Check - - - Versioin check failed. Please try again later. - - - %AppName% Update Check Result - - - New version {0} is available. Update? - - - Downloading updater failed. Try again later. - - - New version is available but download failed. Try again later. - - - New version is not found. Latest version is {0}. Download it? - - - Your %AppName% is latest; you don't need to update. Version: {0} Latest version: {1} - - - Version check failed - - - Delete all tweets in this tab {0} ? (posts aren't deleted from the server.) - - - Confirm Clearing Tab - - - (Icon fetch failed) - - - (Choice the tweet) - - - Delete selected tweets/messages?{0}WARNING: They are deleted from server too!{0} To remove ID from tab, select [Move ID].{0} To remove tab, select [Delete Tab].{0}{0}To cancel operation, select [Cancel]. - - - Check removing - - - Remove failed - - - Remove succeeded - - - Fetching interval must a value in 0 or 15 to 6000. - - - Fetching interval must a value in 0 or 15 to 6000. - - - Invalid regular expression pattern. - - - No matches found. - - - Find - - - Mark favorite those selected tweets? - - - Check favoring - - - Favoring - - - No fav added - - - Unmark favorite those selected tweets? - - - Check favoring - - - Unfavoring - - - No fav removed - - - Refreshing... - - - Recent refreshed - - - Initial fetch completed - - - DMRcv refreshed - - - DMSnt refreshing... - - - DMSnt refreshed - - - POST completed - - - Mark fav({0}/{1}) failed:{2} - - - Unmark fav({0}/{1}) failed:{2} - - - Confirm continue reading - - - Reply refreshing...{0}pages - - - Recent refreshing...{0}pages - - - DMRcv refreshing...{0}pages - - - Reply refreshed - - - (New Tab) - - - Tab ""{0}"" is already exists; please specify other name. - - - Add tab - - - Leave in Recent? - - - Moving - - - Make post mark? - - - Marking - - - This configuration file was generated by %AppName% automatically. Do not modify by hand. - - - Invalid regular expression pattern. - - - No matches found. - - - Find - - - Invalid regular expression pattern. - - - No matches found. - - - Find - - - POST completed - - - Recent refreshing... - - - Recent refreshing... - - - Reply refreshing... - - - DMRcv refreshing... - - - New {0} tweets - - - Load log - - - Initial loading - - - Remove this tab?{0} - - - Confirm removing tab - - - Save all selected tweets?{0} [Yes]: Save all tweets{0} [No]: Save all SELECTED tweets{0} [Cancel]: Cancel to save.{0}(Save as Tab-Separated-Text) - - - Select save target - - - TSV files (*.tsv)|*.tsv|All files (*.*)|*.* - - - Specify save as... - - - Specify username and password. - - - Invalid username (E-mail address is not allowed in username) - - - Invalid setting value. - - - https://en.wikipedia.org/w/index.php?search={0} - - - https://www.google.com/search?q={0} - - - https://twitter.com/search?q={0} - - - [User: {0}] - - - Make post mark - - - Copy/ - - - [User: (All)] - - - [Body: - - - ] - - - Complex/ - - - Simple/ - - - Regexp/ - - - URL/ - - - Move - - - {0} (Not Read Reply) - - - {0} (Not Read) - - - {0} ({1}) (Reply) - - - {0}/{1} (Not Read/All) - - - [Tab: {0}/{1} All: {2}/{3} (Reply: {4})] [Spd: Pst {5}/ Fav {6}/ TL {7}] [Interval: - - - -] - - - ] - - - Reading page number must be number 1 to 999. - - - Reading page number must be number 1 to 999. - - - Reading page number must be number 1 to 999. - - - Reading page number must be number 1 to 999. - - - Reading page number must be number 1 to 999. - - - Reading page number must be number 1 to 999. - - - %AppName% is already running. If you want to run multiple %AppName% processes, change the path to settings location by the /configDir:<dirpath> option or run the {0}.exe from another folder. - - - %AppName% - - - (New Tab) - - - Tab ""{0}"" is already exists; please specify other name. - - - Add tab - - - Port number must be integer number. - - - Port number must be number 0 to 65535. - - - Refresh interval must be number 0 or 15 to 6000 - - - Refresh interval must be number 0 or 15 to 6000 - - - DMRcv refreshing... - - - Recent refreshing... - - - Please send this file to {0}. - - - Please tweet to {0} in Twitter if you can. - - - Environment: - - - Operating System: {0} - - - Common Language Runtime: {0} - - - {0}.exe Version: {1} - - - Version {0} - - - **** Error Log: {0} **** - - - Error - - - Please send this file to {0}. - - - Please tweet to {0} in Twitter if you can. - - - Environment: - - - Operating System: {0} - - - Common Language Runtime: {0} - - - {0}.exe Version: {1} - - - Exception {0}: {1} - - - We are sorry but error was happened. A log text was created as {0} in same folder of %AppName%. Please send this to {1} or{3}tweet to {2} in Twitter.{3}[OK] to open log file. [Cancel] to continue. - - - Followers refreshing... - - - Followers refresh error: - - - Followers refreshed - - - Getting number of tweet in Api-mode must be 20 to 200. - - - Date - - - Tab ""{0}"" is already exists; please specify other name. - - - Rename tab - - - Administrator authority: - - - Users authority: - - - Fav refreshing... - - - Fav refreshed - - - <<Exclude>> - - - CaseSensitive/ - - - API Information - - - * Failed to get API information. * - - - Please input user ID. - - - Failed : - - - Done! - - - The length of the tweet exceeds the limit. Are you sure you want to force the post? - - - Tweet length exceeded - - - Retweet this tweet? - - - Filtered Timeline - - - Your profile info don't taken yet. Please try again after posting the tweet. - - - Will you delete these selecting hashtags? - - - >>> Following - - - >>> NOT Following - - - <<< Followed - - - <<< NOT Followed - - - Relationship - - - Authentication success - - - Authentication failed - - - Authenticated - - - Not authenticated - - - Press [Start Authentication] button and [Authorize App]. Key in PIN then press [Finish] button. Will you exit application without validating your account? - - - User Information analyze failed. - - - Fetching interval must a value in 0 or 30 to 6000. - - - Fetching interval must a value in 0 or 30 to 6000. - - - Tweets: {0} Following: {1} Followers: {2}({3}) - - - Select a media file to upload - - - [Service: {0}] -Do you want to upload the {1} selected media file(s)? - - - Confirm to upload - - - Please select a service to upload the media file. - - - Media sharing service - - - This tweet isn't changed. Post this tweet as Official Retweet?{0}[Yes:Official Retweet]{0}[No:resume]{0}[Cancel:abort to post] - - - Getting Api Information... - - - : Unblock this user? - - - Confirm unblock - - - Failed to unblock. - - - Unbloked. - - - : Block this user? - - - Confirm block. - - - Failed to block. - - - Success to block. - - - Can't add duplicated rule. - - - : Report spam this user? - - - Confirm Sapm Report - - - Failed to report spam. - - - Spam reported. Please confirm the result in web. - - - Select a tab copy to. - - - Select a tab move to. - - - : Unfollow this user? - - - Confirm unfollowing - - - Now getting API informations... - - - Images(*.gif;*.jpg;*.jpeg;*.png)|*.gif;*.jpg;*.jpeg;*.png - - - The icon file size is limited under 700kb. - - - Now changing icon... - - - Caution: Please confirm the icon after next tweet, if error was occured but icon was already updated. - - - Success to chage icon. - - - Invalid datetime format. - - - The timeout seconds must be between 10 to 120. - - - Warning: Haven't copied the tweets of protected users. - - - Invalid datetime format. - - - Now getting the profile... - - - Following... - - - Unfollowing... - - - time(s) retweeted. - - - Failed to get retweeted count. - - - Now getting relations... - - - Failed to get latest tweet. - - - DirectMessage - - - Favorites - - - Timeline - - - Lists - - - Reply - - - PublicSearch - - - Distributed Timeline - - - Accept - - - Updating Profile... - - - Delete this Lists? - - - Remove this member from this Lists? - - - Failed to delete this member from this Lists. ({0}) - - - Failed to get members. ({0}) - - - Lists name required. - - - Failed to update Lists informations. ({0}) - - - Failed to get Lists. ({0}) - - - Getting Lists informations. Please wait... - - - : Manage Lists - - - Title: - - - Posted at: - - - Likes: - - - Views: - - - Comments: - - - Length: - - - Title: - - - Length: - - - Posted at: - - - Views: - - - Adding to favorites being able to do at a time is up to {0}. - - - Getting number of tweet in Api-mode must be 20 to 100. - - - Retweet being able to do at a time is up to 15. - - - Retweet this tweet? - - - Mark favorite and retweet those selected tweets? - - - Mark favorite and retweet this tweet? - - - Mark favorite and retweet(unofficial) those selected tweets? - - - Really Unfollow? - - - Confirm Unfollow - - - UserTimeline - - - Get members(&M) - - - Get more(&M) - - - Failed to connect auth server. - - - Type PIN code. - - - You are not authorized. - - - Please do Authentication processing to get/send Direct Messages again. - - - Invalid Email address. - - - Thank you for registration! - - - Delete selected rules? ({0} nums) - - - This file type forbidden to use as icon image. - - - Disabled - - - Enabled - - - Faild to get relation info. - - - Syntax Error : - - - Lambda Expression Syntax Check - - - Title: - - - PlayTime: - - - Posted at: - - - Views: - - - Comments: - - - MyLists: - - - No - - - Get counts... - - - Save events?{0} [Yes] :Save events in this tab{0} [No] :Save all events{0}[Cancel]:Cancel{0}(Save as Tab separated text(TSV)) - - - en - - - Failed to add tab. - - - Getting BlockIds... - - - Failed to get BlockIds: - - - Done to get BlockIds - - - Yes - - - Failed to start browser. Error code: {0} - - - &Delete - - - Undo Retweet (&D) - - - The configuration directory ({0}) specified by the "/configDir" option does not exist or is not accessible. - - - Open URL - - - Enter the URL of the tweet you want to open. - - - The input URL is not valid. - - - Failed to load the tweet. ({0}) - - - The tab "{0}" was already exists. Please remove the tab and try again. - - - [Service: {0}] + PostsList + (New Tab) + Name + Post + Date + Date + Username + Tab ""{0}"" is already exists; please specify other name. + Add tab + API Information + * Failed to get API information. * + Getting Api Information... + Authentication success + Authentication failed + Authenticated + Not authenticated + Failed to connect auth server. + Failed to authorize. ({0}) + Failed to start browser. Error code: {0} + Executable (*.exe)|*.exe|All files (*.*)|*.* + Choose the web browser + : Block this user? + Confirm block. + Failed to block. + Success to block. + : Unblock this user? + Confirm unblock + Failed to unblock. + Unbloked. + Delete this rules? {0} 『{1}』 + Confirm deleting rule + Delete selected rules? ({0} nums) + Choice the rule. + Rule checking + Invalid regular expression pattern. + Can't add duplicated rule. + : Report spam this user? + Confirm Sapm Report + Failed to report spam. + Spam reported. Please confirm the result in web. + Select a tab copy to. + Select a tab move to. + : Unfollow this user? + Confirm unfollowing + Now getting API informations... + Images(*.gif;*.jpg;*.jpeg;*.png)|*.gif;*.jpg;*.jpeg;*.png + The icon file size is limited under 700kb. + Now changing icon... + Caution: Please confirm the icon after next tweet, if error was occured but icon was already updated. + Success to chage icon. + This file type forbidden to use as icon image. + Do you really want to change icon? + %AppName% Update Check + Versioin check failed. Please try again later. + %AppName% Update Check Result + New version {0} is available. Update? + Downloading updater failed. Try again later. + New version is available but download failed. Try again later. + New version is not found. Latest version is {0}. Download it? + Your %AppName% is latest; you don't need to update. Version: {0} Latest version: {1} + Version check failed + This software requires {0} or later version. + Delete all tweets in this tab {0} ? (posts aren't deleted from the server.) + Confirm Clearing Tab + Invalid datetime format. + The configuration directory ({0}) specified by the "/configDir" option does not exist or is not accessible. + The timeout seconds must be between 10 to 120. + (Icon fetch failed) + (Choice the tweet) + Warning: Haven't copied the tweets of protected users. + Invalid datetime format. + Will you delete these selecting hashtags? + &Delete + Undo Retweet (&D) + Delete selected tweets/messages?{0}WARNING: They are deleted from server too!{0} To remove ID from tab, select [Move ID].{0} To remove tab, select [Delete Tab].{0}{0}To cancel operation, select [Cancel]. + Check removing + Remove failed + Remove succeeded + Disable + Disabled + Fetching interval must a value in 0 or 15 to 6000. + Fetching interval must a value in 0 or 15 to 6000. + Now getting the profile... + Invalid regular expression pattern. + No matches found. + Find + Enable + Enabled + Mark favorite those selected tweets? + Check favoring + Favoring + No fav added + Adding to favorites being able to do at a time is up to {0}. + Mark favorite and retweet those selected tweets? + Mark favorite and retweet(unofficial) those selected tweets? + Mark favorite and retweet this tweet? + Unmark favorite those selected tweets? + Check favoring + Unfavoring + No fav removed + Following... + Refreshing... + Please input user ID. + Failed : + Done! + >>> Following + >>> NOT Following + <<< Followed + <<< NOT Followed + Relationship + Faild to get relation info. + Really Unfollow? + Confirm Unfollow + Recent refreshed + Initial fetch completed + DMRcv refreshed + DMSnt refreshing... + DMSnt refreshed + POST completed + Mark fav({0}/{1}) failed:{2} + Unmark fav({0}/{1}) failed:{2} + Fav refreshing... + Fav refreshed + Confirm continue reading + Reply refreshing...{0}pages + Recent refreshing...{0}pages + DMRcv refreshing...{0}pages + Reply refreshed + (New Tab) + Tab ""{0}"" is already exists; please specify other name. + Add tab + Leave in Recent? + Moving + Make post mark? + Marking + [Image: {0}] + Filtered Timeline + Syntax Error : + Lambda Expression Syntax Check + Delete this Lists? + Remove this member from this Lists? + Failed to delete this member from this Lists. ({0}) + Failed to get members. ({0}) + Get members(&M) + Get more(&M) + Lists name required. + Failed to update Lists informations. ({0}) + Failed to get Lists. ({0}) + Getting Lists informations. Please wait... + This configuration file was generated by %AppName% automatically. Do not modify by hand. + Loading... + Invalid regular expression pattern. + No matches found. + Find + Invalid regular expression pattern. + No matches found. + Find + (Mute) + : Manage Lists + Title: + PlayTime: + Posted at: + Views: + Comments: + MyLists: + No + Open URL + Enter the URL of the tweet you want to open. + The input URL is not valid. + Failed to load the tweet. ({0}) + Tweets: {0} Following: {1} Followers: {2}({3}) + Select a media file to upload + This tweet isn't changed. Post this tweet as Official Retweet?{0}[Yes:Official Retweet]{0}[No:resume]{0}[Cancel:abort to post] + Are you sure to you want to post this text? +{0} + The length of the tweet exceeds the limit. Are you sure you want to force the post? + Tweet length exceeded + [Service: {0}] +Do you want to upload the {1} selected media file(s)? + Confirm to upload + Do you want to paste image from clipboard? + Please select a service to upload the media file. + Media sharing service + [Service: {0}] "{2}" is unsupported file type. Use other service. File: {3} -Available service: {1} - - - Select media - - - [Service: {0}] +Available service: {1} + Select media + [Service: {0}] File is too large. Reduce the file size, or use other service. File: {2} -Available service: {1} - - - none - - - Failed to get MuteUserIds: {0} - - - Done to get MuteUserIds - - - Getting MuteUserIds... - - - This software requires {0} or later version. - - - Do you really want to change icon? - - - (Mute) - - - Loading... - - - Disable - - - Enable - - - Do you want to paste image from clipboard? - - - Search Results - - - Unable to access Twitter API. +Available service: {1} + none + POST completed + Recent refreshing... + Fetching interval must a value in 0 or 30 to 6000. + Fetching interval must a value in 0 or 30 to 6000. + [Quote @{0}: {1}] + Please do Authentication processing to get/send Direct Messages again. + Recent refreshing... + Reply refreshing... + DMRcv refreshing... + New {0} tweets + Load log + Initial loading + Invalid Email address. + Thank you for registration! + Unfollowing... + Remove this tab?{0} + Confirm removing tab + Retweet being able to do at a time is up to 15. + Retweet this tweet? + Retweet this tweet? + Get counts... + time(s) retweeted. + Failed to get retweeted count. + Specify username and password. + Invalid username (E-mail address is not allowed in username) + Invalid setting value. + Type PIN code. + Save all selected tweets?{0} [Yes]: Save all tweets{0} [No]: Save all SELECTED tweets{0} [Cancel]: Cancel to save.{0}(Save as Tab-Separated-Text) + Select save target + TSV files (*.tsv)|*.tsv|All files (*.*)|*.* + Specify save as... + Save events?{0} [Yes] :Save events in this tab{0} [No] :Save all events{0}[Cancel]:Cancel{0}(Save as Tab separated text(TSV)) + https://en.wikipedia.org/w/index.php?search={0} + https://www.google.com/search?q={0} + https://twitter.com/search?q={0} + Search Results + Succeeded to send DM. + Failed to send DM. + [User: {0}] + Make post mark + Copy/ + <<Exclude>> + CaseSensitive/ + [User: (All)] + [Body: + ] + Complex/ + Simple/ + Regexp/ + URL/ + Move + {0} (Not Read Reply) + {0} (Not Read) + {0} ({1}) (Reply) + {0}/{1} (Not Read/All) + [Tab: {0}/{1} All: {2}/{3} (Reply: {4})] [Spd: Pst {5}/ Fav {6}/ TL {7}] [Interval: + -] + ] + Press [Start Authentication] button and [Authorize App]. Key in PIN then press [Finish] button. Will you exit application without validating your account? + Failed to write settings to {0}. + +Existing setting files are copied to {1}. +(The setting files in {1} will be used at next startup) + Now getting relations... + User Information analyze failed. + Failed to get latest tweet. + Your profile info don't taken yet. Please try again after posting the tweet. + Unable to access Twitter API. [{0}] * Please confirm the network settings. * Please confirm whether your PC's clock is accurate. (It may fail to authentication when clock is delayed.) - * Please re-add the Twitter account in the settings dialog. - - - Succeeded to send DM. - - - Failed to send DM. - - - [Image: {0}] - - - PostsList - - - [Quote @{0}: {1}] - - - {0} characters remaining - - - Failed to update status. ---> [ {0} ] + * Please re-add the Twitter account in the settings dialog. + Reading page number must be number 1 to 999. + Reading page number must be number 1 to 999. + Reading page number must be number 1 to 999. + Reading page number must be number 1 to 999. + Reading page number must be number 1 to 999. + Reading page number must be number 1 to 999. + %AppName% is already running. If you want to run multiple %AppName% processes, change the path to settings location by the /configDir:<dirpath> option or run the {0}.exe from another folder. + %AppName% + {0} characters remaining + Failed to update status. ---> [ {0} ] "{1}" -Do you retry to update status? - - - Failed to write settings to {0}. - -Existing setting files are copied to {1}. -(The setting files in {1} will be used at next startup) - - - It is not recommended to run {0} as administrator. +Do you retry to update status? + (New Tab) + Tab ""{0}"" is already exists; please specify other name. + Add tab + The tab "{0}" was already exists. Please remove the tab and try again. + Tab ""{0}"" is already exists; please specify other name. + Rename tab + DirectMessage + Favorites + Timeline + Lists + Reply + PublicSearch + Distributed Timeline + UserTimeline + Getting number of tweet in Api-mode must be 20 to 200. + Port number must be integer number. + Port number must be number 0 to 65535. + Getting number of tweet in Api-mode must be 20 to 100. + Refresh interval must be number 0 or 15 to 6000 + Refresh interval must be number 0 or 15 to 6000 + DMRcv refreshing... + Recent refreshing... + Please send this file to {0}. + Please tweet to {0} in Twitter if you can. + Environment: + Operating System: {0} + Common Language Runtime: {0} + {0}.exe Version: {1} + en + Version {0} + Failed to add tab. + You are not authorized. + **** Error Log: {0} **** + Error + Administrator authority: + Users authority: + Please send this file to {0}. + Please tweet to {0} in Twitter if you can. + Environment: + Operating System: {0} + Common Language Runtime: {0} + {0}.exe Version: {1} + Exception {0}: {1} + We are sorry but error was happened. A log text was created as {0} in same folder of %AppName%. Please send this to {1} or{3}tweet to {2} in Twitter.{3}[OK] to open log file. [Cancel] to continue. + Getting BlockIds... + Failed to get BlockIds: + Done to get BlockIds + Followers refreshing... + Followers refresh error: + Followers refreshed + Failed to get MuteUserIds: {0} + Done to get MuteUserIds + Getting MuteUserIds... + To use Bitly, you must perform the Bitly authentication in settings dialog. + Accept + Updating Profile... + Title: + Posted at: + Likes: + Views: + Comments: + Length: + It is not recommended to run {0} as administrator. * {0} does not require administrator privileges. * If you run as administrator, operations to post images with D&D will be restricted. - * After running, the setting files of {0} will be able to modify only from administrator. - - - Failed to authorize. ({0}) - - - To use Bitly, you must perform the Bitly authentication in settings dialog. - - - Are you sure to you want to post this text? -{0} - - \ No newline at end of file + * After running, the setting files of {0} will be able to modify only from administrator. + Yes + Title: + Length: + Posted at: + Views: + diff --git a/OpenTween/Properties/Resources.resx b/OpenTween/Properties/Resources.resx index b06eb0b12..5e2a744da 100644 --- a/OpenTween/Properties/Resources.resx +++ b/OpenTween/Properties/Resources.resx @@ -1,1187 +1,380 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - (新規タブ) - - - 名前 - - - 投稿 - - - 取得日時 - - - ユーザ名 - - - タブ ""{0}"" は既に存在するため、追加できません。別の名前を指定してください。 - - - タブ追加 - - - - ..\Resources\5b.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\6b.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\5r.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\5y.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - 実行形式ファイル(*.exe)|*.exe|すべてのファイル(*.*)|*.* - - - ブラウザを指定してください - - - このルールを削除してもよろしいですか?{0} 『{1}』 - - - ルール削除確認 - - - ルールを指定してください。 - - - ルールチェック - - - 正規表現エラー: - - - ..\Resources\ChangeLog.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - - %AppName%更新確認 - - - 更新版のバージョン取得に失敗しました。しばらく待ってから再度お試しください。 - - - %AppName%更新結果 - - - 新しいバージョン {0} が公開されています。更新しますか? - - - アップデーターのダウンロードに失敗しました。しばらく待ってから再度お試しください。 - - - 最新版が公開されていますが、ダウンロードに失敗しました。しばらく待ってから再度お試しください。 - - - 新しいバージョンは見つかりません。 {0} が公開されています。強制的に更新しますか? - - - 最新版をお使いです。更新の必要はありませんでした。使用中Ver:{0} 最新Ver:{1} - - - バージョンチェック失敗 - - - このタブの発言をクリアしてもよろしいですか?{0}(サーバーから発言は削除しません。) - - - タブクリア確認 - - - (アイコンが取得できていません) - - - (発言を選択してください) - - - 選択されている自発言(またはDM)を削除してもよろしいですか?{0}注意 : Twitterサーバからも削除されます!{0} タブからIDを削除する場合は、「IDを移動」を使ってください。{0} タブを削除する場合は、「タブを削除」を使ってください。{0}{0}削除処理を中止するには、「キャンセル」ボタンを押してください。 - - - 削除確認 - - - 削除失敗 - - - 削除成功 - - - 更新間隔には数値(0または15~6000)を指定してください。 - - - 更新間隔には数値(0または15~6000)を指定してください。 - - - 正規表現パターンが間違っています。 - - - 検索条件に一致するデータは見つかりません。 - - - 検索 - - - 選択された発言をFavoritesに追加します。よろしいですか? - - - Fav確認 - - - Fav追加中... - - - Fav追加なし - - - 選択された発言をFavoritesから削除します。よろしいですか? - - - Fav確認 - - - Fav削除中... - - - Fav削除なし - - - 更新中... - - - Recent更新完了 - - - 起動時読込完了 - - - DMRcv更新完了 - - - DMSnt更新中... - - - DMSnt更新完了 - - - POST完了 - - - Fav追加({0}/{1}) 失敗:{2} - - - Fav削除({0}/{1}) 失敗:{2} - - - 読み込み継続確認 - - - Reply更新中...{0}pages - - - Recent更新中...{0}pages - - - DMRcv更新中...{0}pages - - - Reply更新完了 - - - (新規タブ) - - - タブ ""{0}"" は既に存在するため、追加できません。別の名前を指定してください。 - - - タブ追加 - - - Recentに残しますか?{0} 「はい」 :残す{0} 「いいえ」:残さない - - - 移動確認 - - - マークをつけますか?{0} 「はい」 :つける{0} 「いいえ」:つけない - - - マーク確認 - - - この設定ファイルは %AppName% により自動生成されました。手動で変更しないでください。 - - - 正規表現パターンが間違っています。 - - - 検索条件に一致するデータは見つかりません。 - - - 検索 - - - 正規表現パターンが間違っています。 - - - 検索条件に一致するデータは見つかりません。 - - - 検索 - - - ..\Resources\4b.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - POST完了 - - - Recent更新中... - - - ..\Resources\re.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\re2.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\re3.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\re4.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - Recent更新中... - - - Reply更新中... - - - DMRcv更新中... - - - 新着 {0} 件 - - - ログ読込 - - - 起動読込 - - - このタブを削除してもよろしいですか?{0} - - - タブの削除確認 - - - 選択中タブの全発言を保存しますか?{0} 「はい」   :全発言を保存する{0} 「いいえ」  :選択している発言のみ保存する{0} 「キャンセル」:保存処理をキャンセル{0}(タブ区切りのテキストファイル形式で保存します) - - - 保存対象選択 - - - TSVファイル(*.tsv)|*.tsv|すべてのファイル(*.*)|*.* - - - 保存先のファイルを選択してください - - - ユーザー名とパスワードを指定してください。 - - - ユーザー名に『@』を含めないでください。(メールアドレス不可) - - - 設定値に誤りがあります。 - - - https://ja.wikipedia.org/w/index.php?search={0} - - - https://www.google.com/search?hl=ja&q={0} - - - https://twitter.com/search?q={0} - - - [ユーザ・・・{0}] - - - マークする - - - コピーする/ - - - [ユーザ・・・(全て)] - - - [本文・・・ - - - ] - - - 複合/ - - - 単一/ - - - Regexp/ - - - URL/ - - - 移動する - - - {0}件 (未読@) - - - {0}件 (未読) - - - {0} ({1})件 (未読) - - - {0}/{1}件 (未読/総件数) - - - [タブ: {0}/{1} 全体: {2}/{3} (返信: {4})] [時速: 投 {5}/ ☆ {6}/ 流 {7}] [間隔: - - - -] - - - ] - - - 読み込みページ数には数値(1~999)を指定してください。 - - - 読み込みページ数には数値(1~999)を指定してください。 - - - 読み込みページ数には数値(1~999)を指定してください。 - - - 読み込みページ数には数値(1~999)を指定してください。 - - - 読み込みページ数には数値(0~999)を指定してください。 - - - 読み込みページ数には数値(0~999)を指定してください。 - - - %AppName%は既に起動されています。2重起動する場合は /configDir オプションを使用して設定ファイルを分離するか、別フォルダの{0}.exeを実行してください。 - - - %AppName%二重起動チェック - - - ..\Resources\3b.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - (新規タブ) - - - タブ ""{0}"" は既に存在するため、追加できません。別の名前を指定してください。 - - - タブ追加 - - - ポート番号には整数値を指定してください。 - - - ポート番号には0~65535を指定してください。 - - - 更新間隔には数値(0または15~6000)を指定してください。 - - - 更新間隔には数値(0または15~6000)を指定してください。 - - - DMRcv更新中... - - - Recent更新中... - - - このファイルの内容を {0} まで送っていただけると助かります。 - - - ご面倒なら{0}までお知らせ頂くだけでも助かります。 - - - 動作環境: - - - オペレーティング システム: {0} - - - 共通言語ランタイム: {0} - - - {0}.exeのバージョン: {1} - - - バージョン {0} - - - **** エラー ログ: {0} **** - - - エラー発生 - - - このファイルの内容を {0} まで送っていただけると助かります。 - - - ご面倒なら{0}までお知らせ頂くだけでも助かります。 - - - 動作環境: - - - オペレーティング システム: {0} - - - 共通言語ランタイム: {0} - - - {0}.exeのバージョン: {1} - - - 例外 {0}: {1} - - - エラーが発生しました。ごめんなさい。ログをexeファイルのある場所に {0} として作ったので、{1}まで送っていただけると助かります。{3}ご面倒なら{2}までお知らせ頂くだけでも助かります。{3}「はい」ボタンをクリックするとログを開きます。ログを開かない場合は「いいえ」、このまま終了する場合は「キャンセル」ボタンをクリックしてください。 - - - Followers取得中... - - - Followers取得エラー: - - - Followers取得完了 - - - 無効な日時書式指定文字列です - - - 無効な日時書式指定文字列です - - - タイムアウトまでの時間には数値(10~120)を指定してください。 - - - 取得発言数は20~200件を指定してください。 - - - Administrator権限: - - - Users権限: - - - 日時 - - - タブ ""{0}"" は既に存在するため、変更できません。別の名前を指定してください。 - - - タブ名変更 - - - 既に存在するルールは追加できません - - - Fav取得中... - - - Fav取得完了 - - - ..\Resources\5g.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ..\Resources\6g.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - <<除外>> - - - 大小区別/ - - - API情報 - - - * API情報の取得に失敗 * - - - idを入力して下さい。 - - - 失敗 : - - - 完了! - - - 投稿できる文字数の上限を越えています。強制的に投稿しますか? - - - 文字数制限オーバー - - - Retweetしてもよろしいですか? - - - タイムライン振り分け - - - まだあなたのプロフィール情報を取得していません。投稿後に再度お試しください。 - - - 選択しているハッシュタグを削除してもよろしいですか? - - - >>> ◯ フォローしています - - - >>> × フォローしていません - - - <<< ◯ フォローされています - - - <<< × フォローされていません - - - さんとのフォロー関係 - - - 認証しました - - - 認証できませんでした - - - 認証済 - - - 未認証 - - - 「認証開始」ボタンを押すとブラウザが開きます。「連携アプリを認証」し、表示されたPINを画面上部に入力後、「Finish」ボタンを押してください。認証せずに終了してもよろしいですか? - - - いいえ - - - ユーザー情報解析失敗 - - - はい - - - フォロー状況取得失敗 - - - 最新発言の取得に失敗しました - - - 回Retweetされています - - - Retweetカウントの取得に失敗しました - - - 更新間隔には数値(0または30~6000)を指定してください。 - - - 更新間隔には数値(0または30~6000)を指定してください。 - - - プロフィール取得中・・・ - - - Retweetカウント取得中・・・ - - - フォローしています・・・ - - - フォローを解除しています・・・ - - - フォロー状況取得中・・・ - - - タイトル: - - - 再生時間: - - - 投稿日時: - - - 再生数: - - - コメント数: - - - マイリスト数: - - - 発言 {0} フォロー {1} フォロワー {2}({3}) - - - 画像ファイル(*.gif;*.jpg;*.jpeg;*.png)|*.gif;*.jpg;*.jpeg;*.png - - - サイズ700KBまでのアイコン画像ファイルを選択してください - - - アイコン設定中・・・ - - - 注意:Twitterの仕様により、エラーが発生してもアイコンが変更できている場合があります。次回発言の際にご確認ください。 - - - アイコンを変更しました。 次回発言より反映されます。 - - - 適用 - - - プロフィール更新中・・・ - - - をブロック解除します。よろしいですか? - - - ブロック解除確認 - - - エラーが発生しました。成功しているかどうかWebでご確認ください。 - - - ブロック解除を行いました。成功しているかどうかWebでご確認ください。 - - - をブロックします。よろしいですか? - - - ブロック確認 - - - エラーが発生しました。成功しているかどうかWebでご確認ください。 - - - ブロックを行いました。成功しているかどうかWebでご確認ください。 - - - をブロックしスパム報告を行います。よろしいですか? - - - スパム報告確認 - - - エラーが発生しました。成功しているかどうかWebでご確認ください。 - - - ブロックしスパム報告を行いました。成功しているかどうかWebでご確認ください。 - - - をフォロー解除します。よろしいですか? - - - フォロー解除確認 - - - 警告:Protected発言はコピーされていません。 - - - 選択されている{0}件のルールを削除してもよろしいですか? - - - ルールコピー先タブの選択 - - - ルール移動先タブの選択 - - - DirectMessage - - - Favorites - - - タイムライン - - - Lists - - - Reply - - - PublicSearch - - - タイムライン振り分け - - - API情報取得中・・・ - - - API情報取得中・・・ - - - ..\Resources\InitialImage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - 投稿する画像を選択 - - - [投稿先: {0}] -{1} 枚の画像を投稿します。よろしいですか? - - - 画像投稿確認 - - - 投稿する画像または投稿先サービスが選択されていません。 - - - 画像投稿 - - - ..\Resources\MultiMediaImage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - 編集されていないため、公式RTとして投稿します。 よろしいですか?{0}[はい:公式RTで投稿]{0}[いいえ:非公式RTで投稿]{0}[キャンセル:投稿しない] - - - ..\Resources\Description.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - - このリストを削除してもよろしいですか? - - - このユーザーをリストから削除してよろしいですか? - - - メンバーの削除に失敗しました({0}) - - - メンバーの取得に失敗しました({0}) - - - リスト名を入力してください - - - リスト情報の反映に失敗しました({0}) - - - リスト情報の取得に失敗しました({0}) - - - リスト情報を取得しています。しばらくお待ちください... - - - を含むリストの管理 - - - タイトル: - - - 投稿日時: - - - Likes: - - - 再生数: - - - コメント数: - - - 再生時間: - - - タイトル: - - - 再生時間: - - - 投稿日時: - - - 再生数: - - - 一度にFav追加が実行できるのは{0}件までです - - - 取得発言数は20~100件を指定してください。 - - - 一度にRetweetできるのは15件までです - - - 選択された発言をRetweetしてもよろしいですか? - - - 選択された発言をFavoriteに追加してRetweetします。よろしいですか? - - - Favoriteに追加してRetweetします。よろしいですか? - - - RelatedTweets - - - 選択された発言をFavoritesに追加して非公式RTを実行します。よろしいですか? - - - フォロー解除しますか? - - - フォロー解除確認 - - - UserTimeline - - - ja - - - 無効 - - - 有効 - - - ユーザーアイコンとして使用できないファイルです - - - 構文エラー: - - - ラムダ式構文チェック - - - タブ作成エラー - - - 現在のタブに表示されているイベントログを保存しますか?{0} 「はい」  :現在タブに表示されているイベントログを保存する{0} 「いいえ」 :全てのイベントログを保存する{0}「キャンセル」:保存処理をキャンセル{0}(タブ区切りのテキストファイル形式で保存します) - - - BlockIds取得中... - - - BlockIds取得エラー : - - - BlockIds取得完了 - - - 取得(&M) - - - さらに取得(&M) - - - 認証サーバーに接続できませんでした。 - - - PINを入力してください。 - - - You are not authorized. - - - Direct Messageの送受信をするため、もう一度認証処理をして下さい。 - - - Emailアドレスが正しくありません。 - - - 登録ありがとうございます。 - - - 削除(&D) - - - 公式RTの取り消し(&D) - - - ..\Resources\LogoImage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - ブラウザの起動に失敗しました。エラーコード: {0} - - - "/configDir" で指定されたディレクトリ ({0}) は存在しないかアクセスできません。 - - - ツイートURLを開く - - - ツイートの URL を入力して下さい。 - - - 入力された URL が正しくありません。 - - - ツイートの取得に失敗しました ({0}) - - - タブ "{0}" が既に存在するため追加できません。同名のタブを削除して再度やり直して下さい。 - - - [投稿先: {0}] + 発言一覧 + (新規タブ) + 名前 + 投稿 + 取得日時 + 日時 + ユーザ名 + タブ ""{0}"" は既に存在するため、追加できません。別の名前を指定してください。 + タブ追加 + API情報 + * API情報の取得に失敗 * + API情報取得中・・・ + ..\Resources\5b.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\6b.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\5r.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\5y.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + 認証しました + 認証できませんでした + 認証済 + 未認証 + 認証サーバーに接続できませんでした。 + 認証に失敗しました ({0}) + ブラウザの起動に失敗しました。エラーコード: {0} + 実行形式ファイル(*.exe)|*.exe|すべてのファイル(*.*)|*.* + ブラウザを指定してください + をブロックします。よろしいですか? + ブロック確認 + エラーが発生しました。成功しているかどうかWebでご確認ください。 + ブロックを行いました。成功しているかどうかWebでご確認ください。 + をブロック解除します。よろしいですか? + ブロック解除確認 + エラーが発生しました。成功しているかどうかWebでご確認ください。 + ブロック解除を行いました。成功しているかどうかWebでご確認ください。 + このルールを削除してもよろしいですか?{0} 『{1}』 + ルール削除確認 + 選択されている{0}件のルールを削除してもよろしいですか? + ルールを指定してください。 + ルールチェック + 正規表現エラー: + 既に存在するルールは追加できません + をブロックしスパム報告を行います。よろしいですか? + スパム報告確認 + エラーが発生しました。成功しているかどうかWebでご確認ください。 + ブロックしスパム報告を行いました。成功しているかどうかWebでご確認ください。 + ルールコピー先タブの選択 + ルール移動先タブの選択 + をフォロー解除します。よろしいですか? + フォロー解除確認 + API情報取得中・・・ + 画像ファイル(*.gif;*.jpg;*.jpeg;*.png)|*.gif;*.jpg;*.jpeg;*.png + サイズ700KBまでのアイコン画像ファイルを選択してください + アイコン設定中・・・ + 注意:Twitterの仕様により、エラーが発生してもアイコンが変更できている場合があります。次回発言の際にご確認ください。 + アイコンを変更しました。 次回発言より反映されます。 + ユーザーアイコンとして使用できないファイルです + アイコンを変更します。よろしいですか? + ..\Resources\ChangeLog.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + %AppName%更新確認 + 更新版のバージョン取得に失敗しました。しばらく待ってから再度お試しください。 + %AppName%更新結果 + 新しいバージョン {0} が公開されています。更新しますか? + アップデーターのダウンロードに失敗しました。しばらく待ってから再度お試しください。 + 最新版が公開されていますが、ダウンロードに失敗しました。しばらく待ってから再度お試しください。 + 新しいバージョンは見つかりません。 {0} が公開されています。強制的に更新しますか? + 最新版をお使いです。更新の必要はありませんでした。使用中Ver:{0} 最新Ver:{1} + バージョンチェック失敗 + このソフトウェアは {0} 以降が必要です。 + このタブの発言をクリアしてもよろしいですか?{0}(サーバーから発言は削除しません。) + タブクリア確認 + 無効な日時書式指定文字列です + "/configDir" で指定されたディレクトリ ({0}) は存在しないかアクセスできません。 + タイムアウトまでの時間には数値(10~120)を指定してください。 + (アイコンが取得できていません) + (発言を選択してください) + 警告:Protected発言はコピーされていません。 + 無効な日時書式指定文字列です + 選択しているハッシュタグを削除してもよろしいですか? + 削除(&D) + 公式RTの取り消し(&D) + 選択されている自発言(またはDM)を削除してもよろしいですか?{0}注意 : Twitterサーバからも削除されます!{0} タブからIDを削除する場合は、「IDを移動」を使ってください。{0} タブを削除する場合は、「タブを削除」を使ってください。{0}{0}削除処理を中止するには、「キャンセル」ボタンを押してください。 + 削除確認 + 削除失敗 + 削除成功 + ..\Resources\Description.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 + 無効化 + 無効 + 更新間隔には数値(0または15~6000)を指定してください。 + 更新間隔には数値(0または15~6000)を指定してください。 + プロフィール取得中・・・ + 正規表現パターンが間違っています。 + 検索条件に一致するデータは見つかりません。 + 検索 + 有効化 + 有効 + 選択された発言をFavoritesに追加します。よろしいですか? + Fav確認 + Fav追加中... + Fav追加なし + 一度にFav追加が実行できるのは{0}件までです + 選択された発言をFavoriteに追加してRetweetします。よろしいですか? + 選択された発言をFavoritesに追加して非公式RTを実行します。よろしいですか? + Favoriteに追加してRetweetします。よろしいですか? + 選択された発言をFavoritesから削除します。よろしいですか? + Fav確認 + Fav削除中... + Fav削除なし + フォローしています・・・ + 更新中... + idを入力して下さい。 + 失敗 : + 完了! + >>> ◯ フォローしています + >>> × フォローしていません + <<< ◯ フォローされています + <<< × フォローされていません + さんとのフォロー関係 + フォロー状況取得失敗 + フォロー解除しますか? + フォロー解除確認 + Recent更新完了 + 起動時読込完了 + DMRcv更新完了 + DMSnt更新中... + DMSnt更新完了 + POST完了 + Fav追加({0}/{1}) 失敗:{2} + Fav削除({0}/{1}) 失敗:{2} + Fav取得中... + Fav取得完了 + 読み込み継続確認 + Reply更新中...{0}pages + Recent更新中...{0}pages + DMRcv更新中...{0}pages + Reply更新完了 + (新規タブ) + タブ ""{0}"" は既に存在するため、追加できません。別の名前を指定してください。 + タブ追加 + Recentに残しますか?{0} 「はい」 :残す{0} 「いいえ」:残さない + 移動確認 + マークをつけますか?{0} 「はい」 :つける{0} 「いいえ」:つけない + マーク確認 + [画像: {0}] + ..\Resources\InitialImage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + タイムライン振り分け + 構文エラー: + ラムダ式構文チェック + このリストを削除してもよろしいですか? + このユーザーをリストから削除してよろしいですか? + メンバーの削除に失敗しました({0}) + メンバーの取得に失敗しました({0}) + 取得(&M) + さらに取得(&M) + リスト名を入力してください + リスト情報の反映に失敗しました({0}) + リスト情報の取得に失敗しました({0}) + リスト情報を取得しています。しばらくお待ちください... + この設定ファイルは %AppName% により自動生成されました。手動で変更しないでください。 + 読み込み中... + ..\Resources\LogoImage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + 正規表現パターンが間違っています。 + 検索条件に一致するデータは見つかりません。 + 検索 + 正規表現パターンが間違っています。 + 検索条件に一致するデータは見つかりません。 + 検索 + ..\Resources\4b.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\MultiMediaImage.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + (ミュート) + を含むリストの管理 + タイトル: + 再生時間: + 投稿日時: + 再生数: + コメント数: + マイリスト数: + いいえ + ツイートURLを開く + ツイートの URL を入力して下さい。 + 入力された URL が正しくありません。 + ツイートの取得に失敗しました ({0}) + 発言 {0} フォロー {1} フォロワー {2}({3}) + 投稿する画像を選択 + ..\Resources\PlayableOverlayImage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + 編集されていないため、公式RTとして投稿します。 よろしいですか?{0}[はい:公式RTで投稿]{0}[いいえ:非公式RTで投稿]{0}[キャンセル:投稿しない] + この内容で投稿してもよろしいですか? +{0} + 投稿できる文字数の上限を越えています。強制的に投稿しますか? + 文字数制限オーバー + [投稿先: {0}] +{1} 枚の画像を投稿します。よろしいですか? + 画像投稿確認 + クリップボードから画像を貼り付けようとしています。よろしいですか? + 投稿する画像または投稿先サービスが選択されていません。 + 画像投稿 + [投稿先: {0}] "{2}" の投稿には対応していません。他の投稿先を使用してください。 ファイル名: {3} -使用可能な投稿先: {1} - - - 投稿画像選択 - - - [投稿先: {0}] +使用可能な投稿先: {1} + 投稿画像選択 + [投稿先: {0}] ファイルが大きすぎます。ファイルサイズを小さくするか、他の投稿先を使用してください。 ファイル名: {2} -使用可能な投稿先: {1} - - - なし - - - MuteUserIds取得エラー: {0} - - - MuteUserIds取得完了 - - - MuteUserIds取得中... - - - このソフトウェアは {0} 以降が必要です。 - - - アイコンを変更します。よろしいですか? - - - ..\Resources\PlayableOverlayImage.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - - (ミュート) - - - 無効化 - - - 有効化 - - - 読み込み中... - - - クリップボードから画像を貼り付けようとしています。よろしいですか? - - - 検索結果 - - - Twitter API へのアクセスに失敗しました。 +使用可能な投稿先: {1} + なし + POST完了 + Recent更新中... + 更新間隔には数値(0または30~6000)を指定してください。 + 更新間隔には数値(0または30~6000)を指定してください。 + [引用 @{0}: {1}] + Direct Messageの送受信をするため、もう一度認証処理をして下さい。 + ..\Resources\re.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\re2.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\re3.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\re4.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + Recent更新中... + Reply更新中... + DMRcv更新中... + 新着 {0} 件 + ログ読込 + 起動読込 + Emailアドレスが正しくありません。 + 登録ありがとうございます。 + フォローを解除しています・・・ + このタブを削除してもよろしいですか?{0} + タブの削除確認 + ..\Resources\5g.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\6g.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + 一度にRetweetできるのは15件までです + Retweetしてもよろしいですか? + 選択された発言をRetweetしてもよろしいですか? + Retweetカウント取得中・・・ + 回Retweetされています + Retweetカウントの取得に失敗しました + ユーザー名とパスワードを指定してください。 + ユーザー名に『@』を含めないでください。(メールアドレス不可) + 設定値に誤りがあります。 + PINを入力してください。 + 選択中タブの全発言を保存しますか?{0} 「はい」   :全発言を保存する{0} 「いいえ」  :選択している発言のみ保存する{0} 「キャンセル」:保存処理をキャンセル{0}(タブ区切りのテキストファイル形式で保存します) + 保存対象選択 + TSVファイル(*.tsv)|*.tsv|すべてのファイル(*.*)|*.* + 保存先のファイルを選択してください + 現在のタブに表示されているイベントログを保存しますか?{0} 「はい」  :現在タブに表示されているイベントログを保存する{0} 「いいえ」 :全てのイベントログを保存する{0}「キャンセル」:保存処理をキャンセル{0}(タブ区切りのテキストファイル形式で保存します) + https://ja.wikipedia.org/w/index.php?search={0} + https://www.google.com/search?hl=ja&q={0} + https://twitter.com/search?q={0} + 検索結果 + DM の送信が完了しました + DM の送信に失敗しました + [ユーザ・・・{0}] + マークする + コピーする/ + <<除外>> + 大小区別/ + [ユーザ・・・(全て)] + [本文・・・ + ] + 複合/ + 単一/ + Regexp/ + URL/ + 移動する + {0}件 (未読@) + {0}件 (未読) + {0} ({1})件 (未読) + {0}/{1}件 (未読/総件数) + [タブ: {0}/{1} 全体: {2}/{3} (返信: {4})] [時速: 投 {5}/ ☆ {6}/ 流 {7}] [間隔: + -] + ] + 「認証開始」ボタンを押すとブラウザが開きます。「連携アプリを認証」し、表示されたPINを画面上部に入力後、「Finish」ボタンを押してください。認証せずに終了してもよろしいですか? + {0} での設定の書き込みに失敗しました。 + +既存の設定ファイルは {1} にコピーされます。 +(次回起動時は {1} の設定ファイルが優先されます) + フォロー状況取得中・・・ + ユーザー情報解析失敗 + 最新発言の取得に失敗しました + まだあなたのプロフィール情報を取得していません。投稿後に再度お試しください。 + Twitter API へのアクセスに失敗しました。 [{0}] ・ネットワーク設定が正しいか確認して下さい ・PC の時計が正しいか確認して下さい (大幅にずれていると認証に失敗することがあります) -・設定画面から Twitter アカウントをもう一度追加し直して下さい - - - DM の送信が完了しました - - - DM の送信に失敗しました - - - [画像: {0}] - - - 発言一覧 - - - [引用 @{0}: {1}] - - - 残り{0}文字 - - - 投稿に失敗しました ---> [ {0} ] +・設定画面から Twitter アカウントをもう一度追加し直して下さい + 読み込みページ数には数値(1~999)を指定してください。 + 読み込みページ数には数値(1~999)を指定してください。 + 読み込みページ数には数値(1~999)を指定してください。 + 読み込みページ数には数値(1~999)を指定してください。 + 読み込みページ数には数値(0~999)を指定してください。 + 読み込みページ数には数値(0~999)を指定してください。 + %AppName%は既に起動されています。2重起動する場合は /configDir オプションを使用して設定ファイルを分離するか、別フォルダの{0}.exeを実行してください。 + %AppName%二重起動チェック + 残り{0}文字 + 投稿に失敗しました ---> [ {0} ] "{1}" -もう一度投稿を試みますか? - - - {0} での設定の書き込みに失敗しました。 - -既存の設定ファイルは {1} にコピーされます。 -(次回起動時は {1} の設定ファイルが優先されます) - - - {0}を管理者権限で実行する事は推奨されません。 +もう一度投稿を試みますか? + ..\Resources\3b.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + (新規タブ) + タブ ""{0}"" は既に存在するため、追加できません。別の名前を指定してください。 + タブ追加 + タブ "{0}" が既に存在するため追加できません。同名のタブを削除して再度やり直して下さい。 + タブ ""{0}"" は既に存在するため、変更できません。別の名前を指定してください。 + タブ名変更 + DirectMessage + Favorites + タイムライン + Lists + Reply + PublicSearch + RelatedTweets + タイムライン振り分け + UserTimeline + 取得発言数は20~200件を指定してください。 + ポート番号には整数値を指定してください。 + ポート番号には0~65535を指定してください。 + 取得発言数は20~100件を指定してください。 + 更新間隔には数値(0または15~6000)を指定してください。 + 更新間隔には数値(0または15~6000)を指定してください。 + DMRcv更新中... + Recent更新中... + このファイルの内容を {0} まで送っていただけると助かります。 + ご面倒なら{0}までお知らせ頂くだけでも助かります。 + 動作環境: + オペレーティング システム: {0} + 共通言語ランタイム: {0} + {0}.exeのバージョン: {1} + ja + バージョン {0} + タブ作成エラー + You are not authorized. + **** エラー ログ: {0} **** + エラー発生 + Administrator権限: + Users権限: + このファイルの内容を {0} まで送っていただけると助かります。 + ご面倒なら{0}までお知らせ頂くだけでも助かります。 + 動作環境: + オペレーティング システム: {0} + 共通言語ランタイム: {0} + {0}.exeのバージョン: {1} + 例外 {0}: {1} + エラーが発生しました。ごめんなさい。ログをexeファイルのある場所に {0} として作ったので、{1}まで送っていただけると助かります。{3}ご面倒なら{2}までお知らせ頂くだけでも助かります。{3}「はい」ボタンをクリックするとログを開きます。ログを開かない場合は「いいえ」、このまま終了する場合は「キャンセル」ボタンをクリックしてください。 + BlockIds取得中... + BlockIds取得エラー : + BlockIds取得完了 + Followers取得中... + Followers取得エラー: + Followers取得完了 + MuteUserIds取得エラー: {0} + MuteUserIds取得完了 + MuteUserIds取得中... + Bitlyを使用するには設定画面で認証情報を入力する必要があります + 適用 + プロフィール更新中・・・ + タイトル: + 投稿日時: + Likes: + 再生数: + コメント数: + 再生時間: + {0}を管理者権限で実行する事は推奨されません。 * {0}は管理者権限を必要とするソフトウェアではありません。 * 管理者権限で実行するとD&Dで画像を投稿する操作が制限されます。 - * {0}の設定ファイルが一般ユーザー権限で編集できなくなります。 - - - 認証に失敗しました ({0}) - - - Bitlyを使用するには設定画面で認証情報を入力する必要があります - - - この内容で投稿してもよろしいですか? -{0} - - \ No newline at end of file + * {0}の設定ファイルが一般ユーザー権限で編集できなくなります。 + はい + タイトル: + 再生時間: + 投稿日時: + 再生数: + diff --git a/OpenTween/SearchWordDialog.en.resx b/OpenTween/SearchWordDialog.en.resx index 7e12bb448..f1b75a007 100644 --- a/OpenTween/SearchWordDialog.en.resx +++ b/OpenTween/SearchWordDialog.en.resx @@ -1,169 +1,24 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 123, 16 - - - Regular Expression - - - 100, 16 - - - Case sensitive - - - 70, 12 - - - Text to Fi&nd: - - - &Find - - - Find in &New Tab - - - Timeline Search - - - 94, 12 - - - Search Operators - - - &Find - - - 70, 12 - - - Text to Fi&nd: - - - Twitter Search - - - Search - - \ No newline at end of file + Search + &Find + &Find + Find in &New Tab + 100, 16 + Case sensitive + 123, 16 + Regular Expression + 70, 12 + Text to Fi&nd: + 70, 12 + Text to Fi&nd: + 94, 12 + Search Operators + Twitter Search + Timeline Search + diff --git a/OpenTween/SearchWordDialog.resx b/OpenTween/SearchWordDialog.resx index a75f60077..a6e2a0f82 100644 --- a/OpenTween/SearchWordDialog.resx +++ b/OpenTween/SearchWordDialog.resx @@ -1,582 +1,163 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - 121, 60 - - - 124, 16 - - - 3 - - - 正規表現を使用する - - - checkTimelineRegex - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPageTimeline - - - 2 - - - True - - - 121, 35 - - - 156, 16 - - - 2 - - - 大文字と小文字を区別する - - - checkTimelineCaseSensitive - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPageTimeline - - - 4 - - - True - - - 6, 9 - - - 100, 12 - - - 0 - - - 検索する文字列(&N) - - - label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPageTimeline - - - 1 - - - 121, 6 - - - 282, 19 - - - 1 - - - textSearchTimeline - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPageTimeline - - - 3 - - - True - - - - Fill - - - 3, 3 - - - 114, 25 - - - 4 - - - 検索(&F) - - - buttonSearchTimeline - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 0 - - - Bottom, Right - - - True - - - 2 - - - True - - - Fill - - - 123, 3 - - - 114, 25 - - - 5 - - - 新規タブに表示(&N) - - - buttonSearchTimelineNew - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 1 - - - 169, 86 - - - 0, 0, 0, 0 - - - 1 - - - 240, 31 - - - 4 - - - tableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPageTimeline - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="buttonSearchTimeline" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonSearchTimelineNew" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> - - - Top, Bottom, Left, Right - - - FlatButtons - - - 4, 25 - - - 0, 0, 0, 0 - - - 3, 3, 3, 3 - - - 409, 117 - - - 0 - - - タイムラインから検索 - - - tabPageTimeline - - - System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabControl - - - 0 - - - True - - - 118, 32 - - - 126, 12 - - - 2 - - - 検索に使用できる演算子 - - - linkLabelSearchHelp - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPagePublic - - - 0 - - - Bottom, Right - - - True - - - 1 - - - True - - - Fill - - - NoControl - - - 3, 3 - - - 109, 25 - - - 0 - - - 検索(&F) - - - buttonSearchPublic - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel2 - - - 0 - - - 294, 86 - - - 0, 0, 0, 0 - - - 1 - - - 115, 31 - - - 3 - - - tableLayoutPanel2 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPagePublic - - - 1 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="buttonSearchPublic" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> - - - True - - - NoControl - - - 6, 9 - - - 100, 12 - - - 0 - - - 検索する文字列(&N) - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPagePublic - - - 2 - - - 121, 6 - - - 285, 19 - - - 1 - - - textSearchPublic - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabPagePublic - - - 3 - - - 4, 25 - - - 3, 3, 3, 3 - - - 409, 117 - - - 1 - - - Twitter検索 - - - tabPagePublic - - - System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tabControl - - - 1 - - - 9, 9 - - - 0, 0, 0, 0 - - - 417, 146 - - - 6 - - - tabControl - - - System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 96, 96 - - - 435, 164 - - - CenterParent - - - 検索 - - - SearchWordDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 435, 164 + True + CenterParent + 検索 + SearchWordDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + buttonSearchPublic + tableLayoutPanel2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + buttonSearchTimeline + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + buttonSearchTimelineNew + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + checkTimelineCaseSensitive + tabPageTimeline + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + checkTimelineRegex + tabPageTimeline + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + label1 + tabPageTimeline + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + label2 + tabPagePublic + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + linkLabelSearchHelp + tabPagePublic + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + tabControl + $this + System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + tableLayoutPanel1 + tabPageTimeline + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + tableLayoutPanel2 + tabPagePublic + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + tabPagePublic + tabControl + System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + tabPageTimeline + tabControl + System.Windows.Forms.TabPage, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + textSearchPublic + tabPagePublic + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + textSearchTimeline + tabPageTimeline + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + True + Fill + NoControl + 3, 3 + 109, 25 + 0 + 検索(&F) + True + Fill + 3, 3 + 114, 25 + 4 + 検索(&F) + True + Fill + 123, 3 + 114, 25 + 5 + 新規タブに表示(&N) + True + 121, 35 + 156, 16 + 2 + 大文字と小文字を区別する + True + 121, 60 + 124, 16 + 3 + 正規表現を使用する + True + 6, 9 + 100, 12 + 0 + 検索する文字列(&N) + True + NoControl + 6, 9 + 100, 12 + 0 + 検索する文字列(&N) + True + 118, 32 + 126, 12 + 2 + 検索に使用できる演算子 + Top, Bottom, Left, Right + FlatButtons + 9, 9 + 0, 0, 0, 0 + 417, 146 + 6 + Bottom, Right + True + 2 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="buttonSearchTimeline" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonSearchTimelineNew" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,50,Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> + 169, 86 + 0, 0, 0, 0 + 1 + 240, 31 + 4 + Bottom, Right + True + 1 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="buttonSearchPublic" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,50" /><Rows Styles="Percent,50" /></TableLayoutSettings> + 294, 86 + 0, 0, 0, 0 + 1 + 115, 31 + 3 + 4, 25 + 3, 3, 3, 3 + 409, 117 + 1 + Twitter検索 + 4, 25 + 0, 0, 0, 0 + 3, 3, 3, 3 + 409, 117 + 0 + タイムラインから検索 + 121, 6 + 285, 19 + 1 + 121, 6 + 282, 19 + 1 + diff --git a/OpenTween/SendErrorReportForm.en.resx b/OpenTween/SendErrorReportForm.en.resx index 34e7d8bc2..9b44f7d7a 100644 --- a/OpenTween/SendErrorReportForm.en.resx +++ b/OpenTween/SendErrorReportForm.en.resx @@ -1,160 +1,23 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Send by &Email - - - Send by D&M - - - &Don't Send - - - - 385, 12 - - - An error has occurred. Please send an error report to help fix the problem. - - - 602, 36 - - - When contains personal information such as username in the error report, please delete directly from the above text. + Inherit + Send Error Report + &Don't Send + &Reset + Send by D&M + Send by &Email + 442, 16 + I don't want my name (screen name) to show up in the changelog entry. (optional) + 385, 12 + An error has occurred. Please send an error report to help fix the problem. + 602, 36 + When contains personal information such as username in the error report, please delete directly from the above text. -If an error report is too long, you might not be able to send by DM. - - - &Reset - - - 442, 16 - - - I don't want my name (screen name) to show up in the changelog entry. (optional) - - - - Inherit - - - Send Error Report - - \ No newline at end of file +If an error report is too long, you might not be able to send by DM. + diff --git a/OpenTween/SendErrorReportForm.resx b/OpenTween/SendErrorReportForm.resx index 3247cfc36..2f80c0181 100644 --- a/OpenTween/SendErrorReportForm.resx +++ b/OpenTween/SendErrorReportForm.resx @@ -1,491 +1,134 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Bottom, Right - - - - 3 - - - Fill - - - NoControl - - - - 3, 2 - - - 3, 2, 3, 2 - - - 111, 25 - - - 0 - - - メールで送信(&E) - - - buttonSendByMail - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 0 - - - 17, 17 - - - Fill - - - NoControl - - - 120, 2 - - - 3, 2, 3, 2 - - - 111, 25 - - - 1 - - - D&Mで送信 - - - buttonSendByDM - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 1 - - - Fill - - - NoControl - - - 237, 2 - - - 3, 2, 3, 2 - - - 113, 25 - - - 2 - - - 送信しない(&D) - - - buttonNotSend - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableLayoutPanel1 - - - 2 - - - 269, 320 - - - 3, 2, 3, 2 - - - 1 - - - 353, 29 - - - 5 - - - tableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="buttonSendByMail" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonSendByDM" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonNotSend" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="Percent,33.33333,Percent,33.33334,Percent,33.33334" /><Rows Styles="Percent,100,Absolute,29" /></TableLayoutSettings> - - - Top, Bottom, Left, Right - - - 12, 53 - - - 3, 2, 3, 2 - - - True - - - Vertical - - - 610, 186 - - - 1 - - - textBoxErrorReport - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 54, 19 - - - 3, 10, 3, 10 - - - 399, 12 - - - 0 - - - エラーが発生しました。お手数ですが、エラーレポートの送信にご協力をお願いします。 - - - label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - Bottom, Left - - - True - - - NoControl - - - 12, 269 - - - 3, 2, 3, 2 - - - 532, 36 - - - 3 - - - もしエラーレポートの中にユーザー名など個人情報が含まれていた場合は、上のテキストから直接削除してください。 + 96, 96 + 634, 361 + True + 3, 4, 3, 4 + エラーレポートを送信 + SendErrorReportForm + System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + bindingSource + System.Windows.Forms.BindingSource, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + buttonNotSend + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + buttonReset + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + buttonSendByDM + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + buttonSendByMail + tableLayoutPanel1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + checkBoxAnonymouns + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + label1 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + label2 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + pictureBoxIcon + $this + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + tableLayoutPanel1 + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + textBoxErrorReport + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + 17, 17 + Fill + NoControl + 237, 2 + 3, 2, 3, 2 + 113, 25 + 2 + 送信しない(&D) + Bottom, Left + NoControl + 12, 322 + 3, 2, 3, 2 + 111, 25 + 4 + リセット(&R) + Fill + NoControl + 120, 2 + 3, 2, 3, 2 + 111, 25 + 1 + D&Mで送信 + Fill + NoControl + 3, 2 + 3, 2, 3, 2 + 111, 25 + 0 + メールで送信(&E) + Bottom, Left + True + NoControl + 14, 246 + 5, 5, 5, 5 + 376, 16 + 2 + 報告者名(スクリーンネーム)の更新履歴への掲載を希望しない(オプション) + True + NoControl + 54, 19 + 3, 10, 3, 10 + 399, 12 + 0 + エラーが発生しました。お手数ですが、エラーレポートの送信にご協力をお願いします。 + Bottom, Left + True + NoControl + 12, 269 + 3, 2, 3, 2 + 532, 36 + 3 + もしエラーレポートの中にユーザー名など個人情報が含まれていた場合は、上のテキストから直接削除してください。 -エラーレポートの文字数によってはDMで送信できない場合があります。 - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Bottom, Left - - - NoControl - - - 12, 322 - - - 3, 2, 3, 2 - - - 111, 25 - - - 4 - - - リセット(&R) - - - buttonReset - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - NoControl - - - 14, 14 - - - 5, 5, 5, 5 - - - 32, 32 - - - Zoom - - - 5 - - - pictureBoxIcon - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - Bottom, Left - - - True - - - NoControl - - - 14, 246 - - - 5, 5, 5, 5 - - - 376, 16 - - - 2 - - - 報告者名(スクリーンネーム)の更新履歴への掲載を希望しない(オプション) - - - checkBoxAnonymouns - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - 96, 96 - - - 634, 361 - - - 3, 4, 3, 4 - - - エラーレポートを送信 - - - bindingSource - - - System.Windows.Forms.BindingSource, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SendErrorReportForm - - - System.Windows.Forms.Form, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file +エラーレポートの文字数によってはDMで送信できない場合があります。 + NoControl + 14, 14 + 5, 5, 5, 5 + 32, 32 + Zoom + 5 + Bottom, Right + 3 + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="buttonSendByMail" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonSendByDM" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonNotSend" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="Percent,33.33333,Percent,33.33334,Percent,33.33334" /><Rows Styles="Percent,100,Absolute,29" /></TableLayoutSettings> + 269, 320 + 3, 2, 3, 2 + 1 + 353, 29 + 5 + Top, Bottom, Left, Right + 12, 53 + 3, 2, 3, 2 + True + Vertical + 610, 186 + 1 + diff --git a/OpenTween/Setting/Panel/ActionPanel.en.resx b/OpenTween/Setting/Panel/ActionPanel.en.resx index 83cda53aa..69d6c4a86 100644 --- a/OpenTween/Setting/Panel/ActionPanel.en.resx +++ b/OpenTween/Setting/Panel/ActionPanel.en.resx @@ -1,229 +1,44 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 157, 16 - - - Disable Drag&&Drop on tab - - - 183, 12 - - - Behavier when doubleclick a tweet - - - Show user's profile - - - Show user's timeline - - - Show Relational tweet - - - Open user's home of twitter.com - - - Open status of twitter.com - - - Not bihavier - - - 189, 16 - - - Open user's home URL with Tab - - - 58, 16 - - - Enable - - - Hotkey - - - 484, 12 - - - Refetch tweets and verify whether marked favorites. This option causes traffic increasement. - - - 149, 16 - - - Check fav result strictly - - - Open... - - - 215, 16 - - - Play sounds when new status arrived - - - 155, 16 - - - Mark your tweets as read - - - 405, 12 - - - Sounds will play when you enable this option and set sound file for each tabs. - - - 126, 16 - - - Enable unread state - - - 88, 12 - - - Path to Browser - - - 150, 16 - - - Close to Exit application - - - 106, 16 - - - Minimize to tray - - - 311, 16 - - - Mark acquired tweets as read when new tweets arrived - - \ No newline at end of file + Open... + 150, 16 + Close to Exit application + 149, 16 + Check fav result strictly + 106, 16 + Minimize to tray + 189, 16 + Open user's home URL with Tab + 311, 16 + Mark acquired tweets as read when new tweets arrived + 155, 16 + Mark your tweets as read + Hotkey + 58, 16 + Enable + 405, 12 + Sounds will play when you enable this option and set sound file for each tabs. + 183, 12 + Behavier when doubleclick a tweet + 88, 12 + Path to Browser + 484, 12 + Refetch tweets and verify whether marked favorites. This option causes traffic increasement. + Show user's profile + Show user's timeline + Show Relational tweet + Open user's home of twitter.com + Open status of twitter.com + Not bihavier + 215, 16 + Play sounds when new status arrived + 157, 16 + Disable Drag&&Drop on tab + 126, 16 + Enable unread state + diff --git a/OpenTween/Setting/Panel/ActionPanel.resx b/OpenTween/Setting/Panel/ActionPanel.resx index 6a0eb8750..49ffb8f99 100644 --- a/OpenTween/Setting/Panel/ActionPanel.resx +++ b/OpenTween/Setting/Panel/ActionPanel.resx @@ -1,855 +1,254 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 23, 274 - - - 164, 16 - - - 32 - - - マウスでのタブ移動を禁止する - - - TabMouseLockCheck - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 24, 251 - - - 142, 12 - - - 30 - - - 発言をダブルクリック時の動作 - - - Label38 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Reply - - - Favorite - - - プロフィール表示 - - - ユーザーのタイムラインを表示 - - - 関連発言表示 - - - ユーザーのHomeを開く - - - ステータスをWebで開く - - - なし - - - 263, 248 - - - 232, 20 - - - 31 - - - ListDoubleClickActionComboBox - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - NoControl - - - 23, 204 - - - 180, 16 - - - 28 - - - ユーザーのホームURLをタブで開く - - - CheckOpenUserTimeline - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 6, 20 - - - 48, 16 - - - 0 - - - 有効 - - - HotkeyCheck - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox3 - - - 0 - - - True - - - NoControl - - - 349, 21 - - - 13, 14 - - - 6 - - - 0 - - - HotkeyCode - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox3 - - - 1 - - - Disable - - - 266, 18 - - - 77, 19 - - - 5 - - - HotkeyText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox3 - - - 2 - - - True - - - NoControl - - - 218, 20 - - - 42, 16 - - - 4 - - - Win - - - HotkeyWin - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox3 - - - 3 - - - True - - - NoControl - - - 173, 20 - - - 39, 16 - - - 3 - - - Alt - - - HotkeyAlt - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox3 - - - 4 - - - True - - - NoControl - - - 119, 20 - - - 48, 16 - - - 2 - - - Shift - - - HotkeyShift - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox3 - - - 5 - - - True - - - NoControl - - - 70, 20 - - - 43, 16 - - - 1 - - - Ctrl - - - HotkeyCtrl - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox3 - - - 6 - - - 24, 296 - - - 473, 43 - - - 33 - - - ホットキー - - - GroupBox3 - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 23, 184 - - - 3, 0, 3, 5 - - - 340, 12 - - - 27 - - - 発言を再取得してFav結果を検証します。通信量が増えるのでOff推奨 - - - Label57 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 23, 165 - - - 183, 16 - - - 26 - - - Fav操作結果を厳密にチェックする - - - CheckFavRestrict - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - NoControl - - - 419, 139 - - - 75, 21 - - - 25 - - - 参照 - - - Button3 - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - True - - - NoControl - - - 23, 13 - - - 113, 16 - - - 17 - - - サウンドを再生する - - - PlaySnd - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - True - - - NoControl - - - 23, 226 - - - 143, 16 - - - 29 - - - 自分の発言を既読にする - - - chkReadOwnPost - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - True - - - NoControl - - - 23, 32 - - - 3, 0, 3, 5 - - - 361, 12 - - - 18 - - - タブのサウンドを設定した上で、「再生する」を選ぶとサウンドが再生されます。 - - - Label15 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - 185, 140 - - - 228, 19 - - - 24 - - - BrowserPathText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - True - - - NoControl - - - 23, 52 - - - 100, 16 - - - 19 - - - 未読管理を行う - - - UReadMng - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 12 - - - True - - - NoControl - - - 23, 143 - - - 60, 12 - - - 23 - - - ブラウザパス - - - Label44 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 13 - - - True - - - NoControl - - - 23, 96 - - - 171, 16 - - - 21 - - - ×ボタンを押したときに終了する - - - CheckCloseToExit - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 14 - - - True - - - NoControl - - - 23, 118 - - - 170, 16 - - - 22 - - - 最小化したときにアイコン化する - - - CheckMinimizeToTray - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 15 - - - True - - - NoControl - - - 23, 74 - - - 145, 16 - - - 20 - - - 新着時に未読をクリアする - - - CheckReadOldPosts - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 16 - - - True - - - 96, 96 - - - 20, 10, 20, 10 - - - ActionPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + 20, 10, 20, 10 + ActionPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + BrowserPathText + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + Button3 + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + CheckCloseToExit + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + CheckFavRestrict + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + CheckMinimizeToTray + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + CheckOpenUserTimeline + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + CheckReadOldPosts + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 16 + chkReadOwnPost + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + GroupBox3 + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + HotkeyAlt + GroupBox3 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + HotkeyCheck + GroupBox3 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + HotkeyCode + GroupBox3 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + HotkeyCtrl + GroupBox3 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + HotkeyShift + GroupBox3 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + HotkeyText + GroupBox3 + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + HotkeyWin + GroupBox3 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + Label15 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + Label38 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + Label44 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + Label57 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + ListDoubleClickActionComboBox + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + PlaySnd + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + TabMouseLockCheck + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + UReadMng + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + 185, 140 + 228, 19 + 24 + NoControl + 419, 139 + 75, 21 + 25 + 参照 + True + NoControl + 23, 96 + 171, 16 + 21 + ×ボタンを押したときに終了する + True + NoControl + 23, 165 + 183, 16 + 26 + Fav操作結果を厳密にチェックする + True + NoControl + 23, 118 + 170, 16 + 22 + 最小化したときにアイコン化する + True + NoControl + 23, 204 + 180, 16 + 28 + ユーザーのホームURLをタブで開く + True + NoControl + 23, 74 + 145, 16 + 20 + 新着時に未読をクリアする + True + NoControl + 23, 226 + 143, 16 + 29 + 自分の発言を既読にする + 24, 296 + 473, 43 + 33 + ホットキー + True + NoControl + 173, 20 + 39, 16 + 3 + Alt + True + NoControl + 6, 20 + 48, 16 + 0 + 有効 + True + NoControl + 349, 21 + 13, 14 + 6 + 0 + True + NoControl + 70, 20 + 43, 16 + 1 + Ctrl + True + NoControl + 119, 20 + 48, 16 + 2 + Shift + Disable + 266, 18 + 77, 19 + 5 + True + NoControl + 218, 20 + 42, 16 + 4 + Win + True + NoControl + 23, 32 + 3, 0, 3, 5 + 361, 12 + 18 + タブのサウンドを設定した上で、「再生する」を選ぶとサウンドが再生されます。 + True + NoControl + 24, 251 + 142, 12 + 30 + 発言をダブルクリック時の動作 + True + NoControl + 23, 143 + 60, 12 + 23 + ブラウザパス + True + NoControl + 23, 184 + 3, 0, 3, 5 + 340, 12 + 27 + 発言を再取得してFav結果を検証します。通信量が増えるのでOff推奨 + Reply + Favorite + プロフィール表示 + ユーザーのタイムラインを表示 + 関連発言表示 + ユーザーのHomeを開く + ステータスをWebで開く + なし + 263, 248 + 232, 20 + 31 + True + NoControl + 23, 13 + 113, 16 + 17 + サウンドを再生する + True + NoControl + 23, 274 + 164, 16 + 32 + マウスでのタブ移動を禁止する + True + NoControl + 23, 52 + 100, 16 + 19 + 未読管理を行う + diff --git a/OpenTween/Setting/Panel/BasedPanel.en.resx b/OpenTween/Setting/Panel/BasedPanel.en.resx index 69cdb86dd..6eb8d1ac7 100644 --- a/OpenTween/Setting/Panel/BasedPanel.en.resx +++ b/OpenTween/Setting/Panel/BasedPanel.en.resx @@ -1,136 +1,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Sign up for Twitter account - - - Start Authentication - - - Remove - - - - 47, 12 - - - Account - - \ No newline at end of file + Remove + Sign up for Twitter account + 47, 12 + Account + Start Authentication + diff --git a/OpenTween/Setting/Panel/BasedPanel.resx b/OpenTween/Setting/Panel/BasedPanel.resx index 7e340e180..b3535e03a 100644 --- a/OpenTween/Setting/Panel/BasedPanel.resx +++ b/OpenTween/Setting/Panel/BasedPanel.resx @@ -1,276 +1,61 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 111, 22 - - - 160, 20 - - - - 8 - - - AuthUserCombo - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - - Bottom, Right - - - True - - - NoControl - - - 310, 320 - - - 186, 25 - - - 11 - - - Twitter アカウントを作成する - - - CreateAccountButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - NoControl - - - 98, 63 - - - 321, 45 - - - 10 - - - 認証開始 - - - StartAuthButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - NoControl - - - 293, 20 - - - 75, 25 - - - 9 - - - 削除 - - - AuthClearButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 25 - - - 49, 12 - - - 7 - - - アカウント - - - Label4 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - 96, 96 - - - BasedPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + BasedPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + AuthClearButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + AuthUserCombo + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + CreateAccountButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + Label4 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + StartAuthButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + True + NoControl + 293, 20 + 75, 25 + 9 + 削除 + 111, 22 + 160, 20 + 8 + Bottom, Right + True + NoControl + 310, 320 + 186, 25 + 11 + Twitter アカウントを作成する + True + NoControl + 23, 25 + 49, 12 + 7 + アカウント + NoControl + 98, 63 + 321, 45 + 10 + 認証開始 + diff --git a/OpenTween/Setting/Panel/ConnectionPanel.en.resx b/OpenTween/Setting/Panel/ConnectionPanel.en.resx index f02b62058..5b77e329b 100644 --- a/OpenTween/Setting/Panel/ConnectionPanel.en.resx +++ b/OpenTween/Setting/Panel/ConnectionPanel.en.resx @@ -1,145 +1,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 371, 12 - - - ※Adjust Connection timeout if the error of timeout happens frequently. - - - 130, 12 - - - Connection timeout(sec) - - - 264, 16 - - - Force to use IPv4 to connect to pbs.twimg.com - - - 220, 12 - - - Connection timeout(sec, Uploading image) - - \ No newline at end of file + 264, 16 + Force to use IPv4 to connect to pbs.twimg.com + 220, 12 + Connection timeout(sec, Uploading image) + 130, 12 + Connection timeout(sec) + 371, 12 + ※Adjust Connection timeout if the error of timeout happens frequently. + diff --git a/OpenTween/Setting/Panel/ConnectionPanel.resx b/OpenTween/Setting/Panel/ConnectionPanel.resx index b43677208..a12be1fc9 100644 --- a/OpenTween/Setting/Panel/ConnectionPanel.resx +++ b/OpenTween/Setting/Panel/ConnectionPanel.resx @@ -1,363 +1,90 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 267, 127 - - - 125, 19 - - - - 7 - - - api.twitter.com - - - False - - - TwitterAPIText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - - NoControl - - - 23, 130 - - - 174, 12 - - - 6 - - - Twitter API URL (api.twitter.com) - - - False - - - Label8 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 23, 75 - - - 3, 3, 3, 3 - - - 231, 12 - - - 4 - - - ※タイムアウトが頻発する場合に調整してください - - - Label64 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - Disable - - - 267, 23 - - - 125, 19 - - - 1 - - - ConnectionTimeOut - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - NoControl - - - 23, 26 - - - 131, 12 - - - 0 - - - タイムアウトまでの時間(秒) - - - Label63 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - True - - - 23, 102 - - - 281, 16 - - - 5 - - - pbs.twimg.com への接続に強制的に IPv4 を使用する - - - checkBoxForceIPv4 - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Disable - - - 267, 48 - - - 125, 19 - - - 3 - - - UploadImageTimeout - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 23, 51 - - - 214, 12 - - - 2 - - - タイムアウトまでの時間(秒, 画像アップロード) - - - label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - 96, 96 - - - ConnectionPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + ConnectionPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + checkBoxForceIPv4 + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ConnectionTimeOut + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + label2 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + Label63 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + Label64 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + Label8 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + TwitterAPIText + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + UploadImageTimeout + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + True + 23, 102 + 281, 16 + 5 + pbs.twimg.com への接続に強制的に IPv4 を使用する + Disable + 267, 23 + 125, 19 + 1 + True + NoControl + 23, 51 + 214, 12 + 2 + タイムアウトまでの時間(秒, 画像アップロード) + True + NoControl + 23, 26 + 131, 12 + 0 + タイムアウトまでの時間(秒) + True + NoControl + 23, 75 + 3, 3, 3, 3 + 231, 12 + 4 + ※タイムアウトが頻発する場合に調整してください + True + NoControl + 23, 130 + 174, 12 + 6 + Twitter API URL (api.twitter.com) + False + 267, 127 + 125, 19 + 7 + api.twitter.com + False + Disable + 267, 48 + 125, 19 + 3 + diff --git a/OpenTween/Setting/Panel/CooperatePanel.en.resx b/OpenTween/Setting/Panel/CooperatePanel.en.resx index ff8a68a85..b754cd70c 100644 --- a/OpenTween/Setting/Panel/CooperatePanel.en.resx +++ b/OpenTween/Setting/Panel/CooperatePanel.en.resx @@ -1,163 +1,22 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 72, 12 - - - Map Provider - - - Zoom Level - - - 82, 12 - - - Thumbnail Size - - - Map Thumbnail - - - 299, 12 - - - Your appoint URL(Replace "{ID}" to tweet's ScreenName) - - - 185, 12 - - - Language at translation destination - - - 196, 16 - - - Shorten nicovideo urls by nico.ms - - - 154, 23 - - - API Key Encryption - - \ No newline at end of file + 196, 16 + Shorten nicovideo urls by nico.ms + 154, 23 + API Key Encryption + 185, 12 + Language at translation destination + 299, 12 + Your appoint URL(Replace "{ID}" to tweet's ScreenName) + 82, 12 + Thumbnail Size + Zoom Level + 72, 12 + Map Provider + Map Thumbnail + diff --git a/OpenTween/Setting/Panel/CooperatePanel.resx b/OpenTween/Setting/Panel/CooperatePanel.resx index f899bfc73..bfd932a41 100644 --- a/OpenTween/Setting/Panel/CooperatePanel.resx +++ b/OpenTween/Setting/Panel/CooperatePanel.resx @@ -1,963 +1,290 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenStreetMap - - - Google Maps - - - - 102, 22 - - - 121, 20 - - - - 1 - - - MapThumbnailProviderComboBox - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MapThumbnailGroupBox - - - 0 - - - True - - - - NoControl - - - 11, 25 - - - 66, 12 - - - 0 - - - 地図サービス - - - label48 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MapThumbnailGroupBox - - - 1 - - - True - - - NoControl - - - 160, 56 - - - 5, 0, 5, 0 - - - 11, 12 - - - 4 - - - x - - - Label42 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MapThumbnailGroupBox - - - 2 - - - 102, 51 - - - 50, 19 - - - 3 - - - MapThumbnailWidthTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MapThumbnailGroupBox - - - 3 - - - 346, 51 - - - 63, 19 - - - 7 - - - MapThumbnailZoomTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MapThumbnailGroupBox - - - 4 - - - 179, 51 - - - 50, 19 - - - 5 - - - MapThumbnailHeightTextBox - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MapThumbnailGroupBox - - - 5 - - - True - - - NoControl - - - 270, 54 - - - 64, 12 - - - 6 - - - ズームレベル - - - Label41 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MapThumbnailGroupBox - - - 6 - - - True - - - NoControl - - - 11, 54 - - - 83, 12 - - - 2 - - - サムネイルサイズ - - - Label40 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MapThumbnailGroupBox - - - 7 - - - 23, 206 - - - 473, 80 - - - 7 - - - 地図サムネイル - - - MapThumbnailGroupBox - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 84 - - - 401, 12 - - - 3 - - - ユーザー指定のURL({ID}をScreenNameに、{STATUS}をステータスIDに置き換えます) - - - Label39 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - 218, 102 - - - 278, 19 - - - 4 - - - UserAppointUrlText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - Afrikaans - - - Albanian - - - Arabic (Saudi Arabia) - - - Arabic (Iraq) - - - Arabic (Egypt) - - - Arabic (Libya) - - - Arabic (Algeria) - - - Arabic (Morocco) - - - Arabic (Tunisia) - - - Arabic (Oman) - - - Arabic (Yemen) - - - Arabic (Syria) - - - Arabic (Jordan) - - - Arabic (Lebanon) - - - Arabic (Kuwait) - - - Arabic (U.A.E.) - - - Arabic (Bahrain) - - - Arabic (Qatar) - - - Basque - - - Bulgarian - - - Belarusian - - - Catalan - - - Chinese (Taiwan) - - - Chinese (PRC) - - - Chinese (Hong Kong SAR) - - - Chinese (Singapore) - - - Croatian - - - Czech - - - Danish - - - Dutch (Standard) - - - Dutch (Belgium) - - - English - - - English (United States) - - - English (United Kingdom) - - - English (Australia) - - - English (Canada) - - - English (New Zealand) - - - English (Ireland) - - - English (South Africa) - - - English (Jamaica) - - - English (Caribbean) - - - English (Belize) - - - English (Trinidad) - - - Estonian - - - Faeroese - - - Farsi - - - Finnish - - - French (Standard) - - - French (Belgium) - - - French (Canada) - - - French (Switzerland) - - - French (Luxembourg) - - - Gaelic (Scotland) - - - Irish - - - German (Standard) - - - German (Switzerland) - - - German (Austria) - - - German (Luxembourg) - - - German (Liechtenstein) - - - Greek - - - Hebrew - - - Hindi - - - Hungarian - - - Icelandic - - - Indonesian - - - Italian (Standard) - - - Italian (Switzerland) - - - Japanese - - - Korean - - - Korean (Johab) - - - Latvian - - - Lithuanian - - - Macedonian (FYROM) - - - Malaysian - - - Maltese - - - Norwegian (Bokmal) - - - Norwegian (Nynorsk) - - - Polish - - - Portuguese (Brazil) - - - Portuguese (Portugal) - - - Rhaeto-Romanic - - - Romanian - - - Romanian (Republic of Moldova) - - - Russian - - - Russian (Republic of Moldova) - - - Sami (Lappish) - - - Serbian (Cyrillic) - - - Serbian (Latin) - - - Slovak - - - Slovenian - - - Sorbian - - - Spanish (Spain) - - - Spanish (Mexico) - - - Spanish (Guatemala) - - - Spanish (Costa Rica) - - - Spanish (Panama) - - - Spanish (Dominican Republic) - - - Spanish (Venezuela) - - - Spanish (Colombia) - - - Spanish (Peru) - - - Spanish (Argentina) - - - Spanish (Ecuador) - - - Spanish (Chile) - - - Spanish (Uruguay) - - - Spanish (Paraguay) - - - Spanish (Bolivia) - - - Spanish (El Salvador) - - - Spanish (Honduras) - - - Spanish (Nicaragua) - - - Spanish (Puerto Rico) - - - Sutu - - - Swedish - - - Swedish (Finland) - - - Thai - - - Tsonga - - - Tswana - - - Turkish - - - Ukrainian - - - Urdu - - - Venda - - - Vietnamese - - - Xhosa - - - Yiddish - - - Zulu - - - 218, 48 - - - 182, 20 - - - 2 - - - ComboBoxTranslateLanguage - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - NoControl - - - 23, 51 - - - 99, 12 - - - 1 - - - 発言翻訳先の言語 - - - Label29 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - True - - - NoControl - - - 23, 23 - - - 237, 16 - - - 0 - - - ニコニコ動画のURLをnico.msで短縮して送信 - - - CheckNicoms - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - True - - - 23, 131 - - - 389, 16 - - - 5 - - - ツイートに含まれる画像URLのサムネイル表示に img.azyobuzi.net を利用する - - - EnableImgAzyobuziNetCheckBox - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - 50, 156 - - - 30, 3, 3, 3 - - - 256, 16 - - - 6 - - - ダイレクトメッセージに含まれるURLには使用しない - - - ImgAzyobuziNetDisabledInDMCheckBox - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - 23, 293 - - - 20, 0, 20, 0 - - - 135, 23 - - - 8 - - - APIキー暗号化 - - - EncryptApiKeyButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 96, 96 - - - CooperatePanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + CooperatePanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null + CheckNicoms + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + ComboBoxTranslateLanguage + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + EnableImgAzyobuziNetCheckBox + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + EncryptApiKeyButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + ImgAzyobuziNetDisabledInDMCheckBox + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + Label29 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + Label39 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + Label40 + MapThumbnailGroupBox + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + Label41 + MapThumbnailGroupBox + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label42 + MapThumbnailGroupBox + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + label48 + MapThumbnailGroupBox + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + MapThumbnailGroupBox + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + MapThumbnailHeightTextBox + MapThumbnailGroupBox + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + MapThumbnailProviderComboBox + MapThumbnailGroupBox + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + MapThumbnailWidthTextBox + MapThumbnailGroupBox + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + MapThumbnailZoomTextBox + MapThumbnailGroupBox + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + UserAppointUrlText + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + True + NoControl + 23, 23 + 237, 16 + 0 + ニコニコ動画のURLをnico.msで短縮して送信 + Afrikaans + Albanian + Arabic (Yemen) + Spanish (Argentina) + Spanish (Ecuador) + Spanish (Chile) + Spanish (Uruguay) + Spanish (Paraguay) + Spanish (Bolivia) + Spanish (El Salvador) + Spanish (Honduras) + Spanish (Nicaragua) + Spanish (Puerto Rico) + Arabic (Syria) + Sutu + Swedish + Swedish (Finland) + Thai + Tsonga + Tswana + Turkish + Ukrainian + Urdu + Venda + Arabic (Jordan) + Vietnamese + Xhosa + Yiddish + Zulu + Arabic (Lebanon) + Arabic (Kuwait) + Arabic (U.A.E.) + Arabic (Bahrain) + Arabic (Qatar) + Basque + Bulgarian + Arabic (Saudi Arabia) + Belarusian + Catalan + Chinese (Taiwan) + Chinese (PRC) + Chinese (Hong Kong SAR) + Chinese (Singapore) + Croatian + Czech + Danish + Dutch (Standard) + Arabic (Iraq) + Dutch (Belgium) + English + English (United States) + English (United Kingdom) + English (Australia) + English (Canada) + English (New Zealand) + English (Ireland) + English (South Africa) + English (Jamaica) + Arabic (Egypt) + English (Caribbean) + English (Belize) + English (Trinidad) + Estonian + Faeroese + Farsi + Finnish + French (Standard) + French (Belgium) + French (Canada) + Arabic (Libya) + French (Switzerland) + French (Luxembourg) + Gaelic (Scotland) + Irish + German (Standard) + German (Switzerland) + German (Austria) + German (Luxembourg) + German (Liechtenstein) + Greek + Arabic (Algeria) + Hebrew + Hindi + Hungarian + Icelandic + Indonesian + Italian (Standard) + Italian (Switzerland) + Japanese + Korean + Korean (Johab) + Arabic (Morocco) + Latvian + Lithuanian + Macedonian (FYROM) + Malaysian + Maltese + Norwegian (Bokmal) + Norwegian (Nynorsk) + Polish + Portuguese (Brazil) + Portuguese (Portugal) + Arabic (Tunisia) + Rhaeto-Romanic + Romanian + Romanian (Republic of Moldova) + Russian + Russian (Republic of Moldova) + Sami (Lappish) + Serbian (Cyrillic) + Serbian (Latin) + Slovak + Slovenian + Arabic (Oman) + Sorbian + Spanish (Spain) + Spanish (Mexico) + Spanish (Guatemala) + Spanish (Costa Rica) + Spanish (Panama) + Spanish (Dominican Republic) + Spanish (Venezuela) + Spanish (Colombia) + Spanish (Peru) + 218, 48 + 182, 20 + 2 + True + 23, 131 + 389, 16 + 5 + ツイートに含まれる画像URLのサムネイル表示に img.azyobuzi.net を利用する + True + 23, 293 + 20, 0, 20, 0 + 135, 23 + 8 + APIキー暗号化 + True + 50, 156 + 30, 3, 3, 3 + 256, 16 + 6 + ダイレクトメッセージに含まれるURLには使用しない + True + NoControl + 23, 51 + 99, 12 + 1 + 発言翻訳先の言語 + True + NoControl + 23, 84 + 401, 12 + 3 + ユーザー指定のURL({ID}をScreenNameに、{STATUS}をステータスIDに置き換えます) + True + NoControl + 11, 54 + 83, 12 + 2 + サムネイルサイズ + True + NoControl + 270, 54 + 64, 12 + 6 + ズームレベル + True + NoControl + 160, 56 + 5, 0, 5, 0 + 11, 12 + 4 + x + True + NoControl + 11, 25 + 66, 12 + 0 + 地図サービス + 23, 206 + 473, 80 + 7 + 地図サムネイル + 179, 51 + 50, 19 + 5 + OpenStreetMap + Google Maps + 102, 22 + 121, 20 + 1 + 102, 51 + 50, 19 + 3 + 346, 51 + 63, 19 + 7 + 218, 102 + 278, 19 + 4 + diff --git a/OpenTween/Setting/Panel/FontPanel.en.resx b/OpenTween/Setting/Panel/FontPanel.en.resx index f8feb6d8f..40e4432a4 100644 --- a/OpenTween/Setting/Panel/FontPanel.en.resx +++ b/OpenTween/Setting/Panel/FontPanel.en.resx @@ -1,199 +1,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Fore... - - - Back to Default - - - Fore... - - - - 119, 12 - - - Details of Tweet(Link) - - - Font&&Fore... - - - 76, 12 - - - Unread Tweet - - - Back... - - - 110, 12 - - - Backcolor of Details - - - Font&&Fore... - - - 90, 12 - - - Details of Tweet - - - 211, 16 - - - Render emoji as an image (Twemoji) - - - Fore... - - - 100, 12 - - - One-way following - - - Fore... - - - 53, 12 - - - Favorited - - - Font&&Fore... - - - 94, 12 - - - Font of tweet list - - - Font && Color - - \ No newline at end of file + Font&&Fore... + Back... + Fore... + Fore... + Font&&Fore... + Fore... + Fore... + Font&&Fore... + Back to Default + 211, 16 + Render emoji as an image (Twemoji) + Font && Color + 119, 12 + Details of Tweet(Link) + 76, 12 + Unread Tweet + 53, 12 + Favorited + 100, 12 + One-way following + 90, 12 + Details of Tweet + 110, 12 + Backcolor of Details + 94, 12 + Font of tweet list + diff --git a/OpenTween/Setting/Panel/FontPanel.resx b/OpenTween/Setting/Panel/FontPanel.resx index fd110b4a4..07eaa69cd 100644 --- a/OpenTween/Setting/Panel/FontPanel.resx +++ b/OpenTween/Setting/Panel/FontPanel.resx @@ -1,993 +1,300 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Top, Right - - - - True - - - NoControl - - - - 384, 146 - - - 75, 25 - - - 14 - - - 文字色 - - - btnRetweet - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 0 - - - Top, Right - - - NoControl - - - 248, 149 - - - 130, 19 - - - 13 - - - This is sample. - - - MiddleLeft - - - lblRetweet - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 1 - - - True - - - NoControl - - - 6, 151 - - - 50, 12 - - - 12 - - - ReTweet - - - Label80 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 2 - - - Bottom - - - True - - - NoControl - - - 180, 304 - - - 10, 10, 10, 10 - - - 112, 25 - - - 25 - - - デフォルトに戻す - - - ButtonBackToDefaultFontColor - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 3 - - - Top, Right - - - True - - - NoControl - - - 384, 230 - - - 75, 25 - - - 21 - - - 文字色 - - - btnDetailLink - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 4 - - - Top, Right - - - NoControl - - - 248, 233 - - - 130, 19 - - - 20 - - - This is sample. - - - MiddleLeft - - - lblDetailLink - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 5 - - - True - - - NoControl - - - 6, 235 - - - 77, 12 - - - 19 - - - 発言詳細リンク - - - Label18 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 6 - - - Top, Right - - - True - - - NoControl - - - 384, 53 - - - 83, 25 - - - 5 - - - フォント&&色 - - - btnUnread - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 7 - - - Top, Right - - - NoControl - - - 248, 56 - - - 130, 19 - - - 4 - - - This is sample. - - - MiddleLeft - - - lblUnread - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 8 - - - True - - - NoControl - - - 6, 58 - - - 62, 12 - - - 3 - - - 未読フォント - - - Label20 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 9 - - - Top, Right - - - True - - - NoControl - - - 384, 261 - - - 75, 25 - - - 24 - - - 背景色 - - - btnDetailBack - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 10 - - - Top, Right - - - NoControl - - - 248, 264 - - - 130, 19 - - - 23 - - - This is sample. - - - MiddleLeft - - - lblDetailBackcolor - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 11 - - - True - - - NoControl - - - 6, 266 - - - 89, 12 - - - 22 - - - 発言詳細背景色 - - - Label37 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 12 - - - Top, Right - - - True - - - NoControl - - - 384, 177 - - - 83, 25 - - - 17 - - - フォント&&色 - - - btnDetail - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 13 - - - Top, Right - - - NoControl - - - 248, 180 - - - 130, 19 - - - 16 - - - This is sample. - - - MiddleLeft - - - lblDetail - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 14 - - - True - - - NoControl - - - 6, 182 - - - 77, 12 - - - 15 - - - 発言詳細文字 - - - Label26 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 15 - - - True - - - 248, 208 - - - 200, 16 - - - 18 - - - 絵文字を画像で表示する (Twemoji) - - - checkBoxUseTwemoji - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 16 - - - Top, Right - - - True - - - NoControl - - - 384, 115 - - - 75, 25 - - - 11 - - - 文字色 - - - btnOWL - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 17 - - - Top, Right - - - NoControl - - - 248, 118 - - - 130, 19 - - - 10 - - - This is sample. - - - MiddleLeft - - - lblOWL - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 18 - - - True - - - NoControl - - - 6, 120 - - - 63, 12 - - - 9 - - - 片思い発言 - - - Label24 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 19 - - - Top, Right - - - True - - - NoControl - - - 384, 84 - - - 75, 25 - - - 8 - - - 文字色 - - - btnFav - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 20 - - - Top, Right - - - NoControl - - - 248, 87 - - - 130, 19 - - - 7 - - - This is sample. - - - MiddleLeft - - - lblFav - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 21 - - - True - - - NoControl - - - 6, 89 - - - 48, 12 - - - 6 - - - Fav発言 - - - Label22 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 22 - - - Top, Right - - - True - - - NoControl - - - 384, 22 - - - 83, 25 - - - 2 - - - フォント&&色 - - - btnListFont - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 23 - - - Top, Right - - - NoControl - - - 248, 25 - - - 130, 19 - - - 1 - - - This is sample. - - - MiddleLeft - - - lblListFont - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 24 - - - True - - - NoControl - - - 6, 27 - - - 62, 12 - - - 0 - - - リストフォント - - - Label61 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox1 - - - 25 - - - 23, 13 - - - 473, 342 - - - 1 - - - フォント&色設定 - - - GroupBox1 - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 96, 96 - - - 20, 10, 20, 10 - - - FontPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + 20, 10, 20, 10 + FontPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + btnDetail + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + btnDetailBack + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + btnDetailLink + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + btnFav + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 20 + btnListFont + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 23 + btnOWL + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 17 + btnRetweet + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + btnUnread + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + ButtonBackToDefaultFontColor + GroupBox1 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + checkBoxUseTwemoji + GroupBox1 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 16 + GroupBox1 + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + Label18 + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label20 + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + Label22 + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 22 + Label24 + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 19 + Label26 + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + Label37 + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + Label61 + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 25 + Label80 + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + lblDetail + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + lblDetailBackcolor + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + lblDetailLink + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + lblFav + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 21 + lblListFont + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 24 + lblOWL + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 18 + lblRetweet + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + lblUnread + GroupBox1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + Top, Right + True + NoControl + 384, 177 + 83, 25 + 17 + フォント&&色 + Top, Right + True + NoControl + 384, 261 + 75, 25 + 24 + 背景色 + Top, Right + True + NoControl + 384, 230 + 75, 25 + 21 + 文字色 + Top, Right + True + NoControl + 384, 84 + 75, 25 + 8 + 文字色 + Top, Right + True + NoControl + 384, 22 + 83, 25 + 2 + フォント&&色 + Top, Right + True + NoControl + 384, 115 + 75, 25 + 11 + 文字色 + Top, Right + True + NoControl + 384, 146 + 75, 25 + 14 + 文字色 + Top, Right + True + NoControl + 384, 53 + 83, 25 + 5 + フォント&&色 + Bottom + True + NoControl + 180, 304 + 10, 10, 10, 10 + 112, 25 + 25 + デフォルトに戻す + True + 248, 208 + 200, 16 + 18 + 絵文字を画像で表示する (Twemoji) + 23, 13 + 473, 342 + 1 + フォント&色設定 + True + NoControl + 6, 235 + 77, 12 + 19 + 発言詳細リンク + True + NoControl + 6, 58 + 62, 12 + 3 + 未読フォント + True + NoControl + 6, 89 + 48, 12 + 6 + Fav発言 + True + NoControl + 6, 120 + 63, 12 + 9 + 片思い発言 + True + NoControl + 6, 182 + 77, 12 + 15 + 発言詳細文字 + True + NoControl + 6, 266 + 89, 12 + 22 + 発言詳細背景色 + True + NoControl + 6, 27 + 62, 12 + 0 + リストフォント + True + NoControl + 6, 151 + 50, 12 + 12 + ReTweet + Top, Right + NoControl + 248, 180 + 130, 19 + 16 + This is sample. + MiddleLeft + Top, Right + NoControl + 248, 264 + 130, 19 + 23 + This is sample. + MiddleLeft + Top, Right + NoControl + 248, 233 + 130, 19 + 20 + This is sample. + MiddleLeft + Top, Right + NoControl + 248, 87 + 130, 19 + 7 + This is sample. + MiddleLeft + Top, Right + NoControl + 248, 25 + 130, 19 + 1 + This is sample. + MiddleLeft + Top, Right + NoControl + 248, 118 + 130, 19 + 10 + This is sample. + MiddleLeft + Top, Right + NoControl + 248, 149 + 130, 19 + 13 + This is sample. + MiddleLeft + Top, Right + NoControl + 248, 56 + 130, 19 + 4 + This is sample. + MiddleLeft + diff --git a/OpenTween/Setting/Panel/FontPanel2.en.resx b/OpenTween/Setting/Panel/FontPanel2.en.resx index fba1ec02a..0a226f053 100644 --- a/OpenTween/Setting/Panel/FontPanel2.en.resx +++ b/OpenTween/Setting/Panel/FontPanel2.en.resx @@ -1,208 +1,37 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 97, 12 - - - Font of input field - - - 169, 12 - - - Backcolor of focused input field - - - 78, 12 - - - Replied Tweet - - - 135, 12 - - - First-time Reading Posts - - - 42, 12 - - - Sounds - - - 145, 12 - - - Colorize One-way following - - - 120, 12 - - - Selected User's Tweet - - - 84, 12 - - - Replies for You - - - 89, 12 - - - Your Own Tweet - - - Font... - - - Back... - - - Back... - - - Back... - - - Back... - - - Back... - - - Back... - - - Back... - - - Back... - - - Back to Default - - - Font && Color - - \ No newline at end of file + Back... + Back... + Back... + Back... + Back... + Font... + Back... + Back... + Back... + Back to Default + Font && Color + 42, 12 + Sounds + 145, 12 + Colorize One-way following + 120, 12 + Selected User's Tweet + 84, 12 + Replies for You + 89, 12 + Your Own Tweet + 78, 12 + Replied Tweet + 169, 12 + Backcolor of focused input field + 97, 12 + Font of input field + 135, 12 + First-time Reading Posts + diff --git a/OpenTween/Setting/Panel/FontPanel2.resx b/OpenTween/Setting/Panel/FontPanel2.resx index c74820a5c..8380ace4a 100644 --- a/OpenTween/Setting/Panel/FontPanel2.resx +++ b/OpenTween/Setting/Panel/FontPanel2.resx @@ -1,1005 +1,304 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 6, 275 - - - 74, 12 - - - 24 - - - 入力欄フォント - - - Label65 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 0 - - - True - - - NoControl - - - 6, 244 - - - 131, 12 - - - 21 - - - 入力欄アクティブ時背景色 - - - Label52 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 1 - - - True - - - NoControl - - - 6, 182 - - - 102, 12 - - - 15 - - - その発言の@先発言 - - - Label49 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 2 - - - True - - - NoControl - - - 6, 213 - - - 53, 12 - - - 18 - - - 一般発言 - - - Label9 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 3 - - - True - - - NoControl - - - 6, 151 - - - 134, 12 - - - 12 - - - その発言の@先の人の発言 - - - Label14 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 4 - - - True - - - NoControl - - - 6, 120 - - - 88, 12 - - - 9 - - - その人への@返信 - - - Label16 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 5 - - - True - - - NoControl - - - 6, 89 - - - 70, 12 - - - 6 - - - その人の発言 - - - Label32 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 6 - - - True - - - NoControl - - - 6, 58 - - - 81, 12 - - - 3 - - - 自分への@返信 - - - Label34 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 7 - - - True - - - NoControl - - - 6, 27 - - - 63, 12 - - - 0 - - - 自分の発言 - - - Label36 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 8 - - - True - - - NoControl - - - 384, 270 - - - 83, 25 - - - 26 - - - フォント&&色 - - - btnInputFont - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 9 - - - True - - - NoControl - - - 384, 239 - - - 75, 25 - - - 23 - - - 背景色 - - - btnInputBackcolor - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 10 - - - True - - - NoControl - - - 384, 177 - - - 75, 25 - - - 17 - - - 背景色 - - - btnAtTo - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 11 - - - True - - - NoControl - - - 384, 208 - - - 75, 25 - - - 20 - - - 背景色 - - - btnListBack - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 12 - - - True - - - NoControl - - - 384, 146 - - - 75, 25 - - - 14 - - - 背景色 - - - btnAtFromTarget - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 13 - - - True - - - NoControl - - - 384, 115 - - - 75, 25 - - - 11 - - - 背景色 - - - btnAtTarget - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 14 - - - True - - - NoControl - - - 384, 84 - - - 75, 25 - - - 8 - - - 背景色 - - - btnTarget - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 15 - - - True - - - NoControl - - - 384, 53 - - - 75, 25 - - - 5 - - - 背景色 - - - btnAtSelf - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 16 - - - True - - - NoControl - - - 384, 22 - - - 75, 25 - - - 2 - - - 背景色 - - - btnSelf - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 17 - - - NoControl - - - 248, 273 - - - 130, 19 - - - 25 - - - This is sample. - - - MiddleLeft - - - lblInputFont - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 18 - - - NoControl - - - 248, 242 - - - 130, 19 - - - 22 - - - This is sample. - - - MiddleLeft - - - lblInputBackcolor - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 19 - - - NoControl - - - 248, 180 - - - 130, 19 - - - 16 - - - This is sample. - - - MiddleLeft - - - lblAtTo - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 20 - - - NoControl - - - 248, 211 - - - 130, 19 - - - 19 - - - This is sample. - - - MiddleLeft - - - lblListBackcolor - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 21 - - - NoControl - - - 248, 149 - - - 130, 19 - - - 13 - - - This is sample. - - - MiddleLeft - - - lblAtFromTarget - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 22 - - - NoControl - - - 248, 118 - - - 130, 19 - - - 10 - - - This is sample. - - - MiddleLeft - - - lblAtTarget - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 23 - - - NoControl - - - 248, 87 - - - 130, 19 - - - 7 - - - This is sample. - - - MiddleLeft - - - lblTarget - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 24 - - - NoControl - - - 248, 56 - - - 130, 19 - - - 4 - - - This is sample. - - - MiddleLeft - - - lblAtSelf - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 25 - - - NoControl - - - 248, 25 - - - 130, 19 - - - 1 - - - This is sample. - - - MiddleLeft - - - lblSelf - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 26 - - - True - - - NoControl - - - 180, 302 - - - 10, 10, 10, 10 - - - 112, 25 - - - 27 - - - デフォルトに戻す - - - ButtonBackToDefaultFontColor2 - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - GroupBox5 - - - 27 - - - 23, 13 - - - 473, 340 - - - 1 - - - フォント&色設定 - - - GroupBox5 - - - System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 96, 96 - - - 20, 10, 20, 10 - - - FontPanel2 - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + 20, 10, 20, 10 + FontPanel2 + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + btnAtFromTarget + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + btnAtSelf + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 16 + btnAtTarget + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + btnAtTo + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + btnInputBackcolor + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + btnInputFont + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + btnListBack + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + btnSelf + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 17 + btnTarget + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + ButtonBackToDefaultFontColor2 + GroupBox5 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 27 + GroupBox5 + $this + System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + Label14 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + Label16 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + Label32 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label34 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + Label36 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + Label49 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Label52 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + Label65 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + Label9 + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + lblAtFromTarget + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 22 + lblAtSelf + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 25 + lblAtTarget + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 23 + lblAtTo + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 20 + lblInputBackcolor + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 19 + lblInputFont + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 18 + lblListBackcolor + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 21 + lblSelf + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 26 + lblTarget + GroupBox5 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 24 + True + NoControl + 384, 146 + 75, 25 + 14 + 背景色 + True + NoControl + 384, 53 + 75, 25 + 5 + 背景色 + True + NoControl + 384, 115 + 75, 25 + 11 + 背景色 + True + NoControl + 384, 177 + 75, 25 + 17 + 背景色 + True + NoControl + 384, 239 + 75, 25 + 23 + 背景色 + True + NoControl + 384, 270 + 83, 25 + 26 + フォント&&色 + True + NoControl + 384, 208 + 75, 25 + 20 + 背景色 + True + NoControl + 384, 22 + 75, 25 + 2 + 背景色 + True + NoControl + 384, 84 + 75, 25 + 8 + 背景色 + True + NoControl + 180, 302 + 10, 10, 10, 10 + 112, 25 + 27 + デフォルトに戻す + 23, 13 + 473, 340 + 1 + フォント&色設定 + True + NoControl + 6, 151 + 134, 12 + 12 + その発言の@先の人の発言 + True + NoControl + 6, 120 + 88, 12 + 9 + その人への@返信 + True + NoControl + 6, 89 + 70, 12 + 6 + その人の発言 + True + NoControl + 6, 58 + 81, 12 + 3 + 自分への@返信 + True + NoControl + 6, 27 + 63, 12 + 0 + 自分の発言 + True + NoControl + 6, 182 + 102, 12 + 15 + その発言の@先発言 + True + NoControl + 6, 244 + 131, 12 + 21 + 入力欄アクティブ時背景色 + True + NoControl + 6, 275 + 74, 12 + 24 + 入力欄フォント + True + NoControl + 6, 213 + 53, 12 + 18 + 一般発言 + NoControl + 248, 149 + 130, 19 + 13 + This is sample. + MiddleLeft + NoControl + 248, 56 + 130, 19 + 4 + This is sample. + MiddleLeft + NoControl + 248, 118 + 130, 19 + 10 + This is sample. + MiddleLeft + NoControl + 248, 180 + 130, 19 + 16 + This is sample. + MiddleLeft + NoControl + 248, 242 + 130, 19 + 22 + This is sample. + MiddleLeft + NoControl + 248, 273 + 130, 19 + 25 + This is sample. + MiddleLeft + NoControl + 248, 211 + 130, 19 + 19 + This is sample. + MiddleLeft + NoControl + 248, 25 + 130, 19 + 1 + This is sample. + MiddleLeft + NoControl + 248, 87 + 130, 19 + 7 + This is sample. + MiddleLeft + diff --git a/OpenTween/Setting/Panel/GetCountPanel.en.resx b/OpenTween/Setting/Panel/GetCountPanel.en.resx index 3b3e8e73c..56cd67a8e 100644 --- a/OpenTween/Setting/Panel/GetCountPanel.en.resx +++ b/OpenTween/Setting/Panel/GetCountPanel.en.resx @@ -1,175 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 30, 12 - - - Lists - - - 72, 12 - - - UserTimeline - - - 75, 12 - - - Public Search - - - 105, 12 - - - Timeline at starting - - - 51, 12 - - - Mentions - - - 53, 12 - - - Favorites - - - 52, 12 - - - Get more - - - 233, 16 - - - Enable to edit fetching number of tweets - - - 199, 12 - - - Fetching number of tweets in timeline - - \ No newline at end of file + 72, 12 + UserTimeline + 51, 12 + Mentions + 30, 12 + Lists + 105, 12 + Timeline at starting + 75, 12 + Public Search + 52, 12 + Get more + 53, 12 + Favorites + 199, 12 + Fetching number of tweets in timeline + 233, 16 + Enable to edit fetching number of tweets + diff --git a/OpenTween/Setting/Panel/GetCountPanel.resx b/OpenTween/Setting/Panel/GetCountPanel.resx index b07da3be5..b5926605c 100644 --- a/OpenTween/Setting/Panel/GetCountPanel.resx +++ b/OpenTween/Setting/Panel/GetCountPanel.resx @@ -1,597 +1,168 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Disable - - - - 337, 193 - - - 58, 19 - - - - 29 - - - ListTextCountApi - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 23, 196 - - - 76, 12 - - - 28 - - - Listsの取得数 - - - Label25 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Disable - - - 337, 251 - - - 58, 19 - - - 33 - - - UserTimelineTextCountApi - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - NoControl - - - 23, 254 - - - 118, 12 - - - 32 - - - UserTimelineの取得数 - - - Label17 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 225 - - - 117, 12 - - - 30 - - - PublicSearchの取得数 - - - Label30 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 23, 138 - - - 63, 12 - - - 24 - - - 初回の更新 - - - Label28 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 23, 55 - - - 87, 12 - - - 19 - - - Mentions取得数 - - - Label19 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - Disable - - - 337, 164 - - - 58, 19 - - - 27 - - - FavoritesTextCountApi - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - Disable - - - 337, 222 - - - 58, 19 - - - 31 - - - SearchTextCountApi - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - True - - - NoControl - - - 23, 167 - - - 99, 12 - - - 26 - - - Favoritesの取得数 - - - Label66 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - Disable - - - 337, 135 - - - 58, 19 - - - 25 - - - FirstTextCountApi - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - Disable - - - 337, 106 - - - 58, 19 - - - 23 - - - GetMoreTextCountApi - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - True - - - NoControl - - - 23, 109 - - - 79, 12 - - - 22 - - - 前データの更新 - - - Label53 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 12 - - - True - - - NoControl - - - 23, 81 - - - 247, 16 - - - 21 - - - 次の項目の更新時の取得数を個別に設定する - - - UseChangeGetCount - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 13 - - - Disable - - - 337, 52 - - - 58, 19 - - - 20 - - - TextCountApiReply - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 14 - - - True - - - NoControl - - - 23, 26 - - - 77, 12 - - - 17 - - - 標準取得件数 - - - Label67 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 15 - - - Disable - - - 337, 23 - - - 58, 19 - - - 18 - - - TextCountApi - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 16 - - - True - - - 96, 96 - - - GetCountPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + GetCountPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + FavoritesTextCountApi + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + FirstTextCountApi + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + GetMoreTextCountApi + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + Label17 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + Label19 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label25 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + Label28 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + Label30 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + Label53 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + Label66 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + Label67 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + ListTextCountApi + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + SearchTextCountApi + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + TextCountApi + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 16 + TextCountApiReply + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + UseChangeGetCount + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + UserTimelineTextCountApi + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Disable + 337, 164 + 58, 19 + 27 + Disable + 337, 135 + 58, 19 + 25 + Disable + 337, 106 + 58, 19 + 23 + True + NoControl + 23, 254 + 118, 12 + 32 + UserTimelineの取得数 + True + NoControl + 23, 55 + 87, 12 + 19 + Mentions取得数 + True + NoControl + 23, 196 + 76, 12 + 28 + Listsの取得数 + True + NoControl + 23, 138 + 63, 12 + 24 + 初回の更新 + True + NoControl + 23, 225 + 117, 12 + 30 + PublicSearchの取得数 + True + NoControl + 23, 109 + 79, 12 + 22 + 前データの更新 + True + NoControl + 23, 167 + 99, 12 + 26 + Favoritesの取得数 + True + NoControl + 23, 26 + 77, 12 + 17 + 標準取得件数 + Disable + 337, 193 + 58, 19 + 29 + Disable + 337, 222 + 58, 19 + 31 + Disable + 337, 23 + 58, 19 + 18 + Disable + 337, 52 + 58, 19 + 20 + True + NoControl + 23, 81 + 247, 16 + 21 + 次の項目の更新時の取得数を個別に設定する + Disable + 337, 251 + 58, 19 + 33 + diff --git a/OpenTween/Setting/Panel/GetPeriodPanel.en.resx b/OpenTween/Setting/Panel/GetPeriodPanel.en.resx index ebc92a02e..949f84f70 100644 --- a/OpenTween/Setting/Panel/GetPeriodPanel.en.resx +++ b/OpenTween/Setting/Panel/GetPeriodPanel.en.resx @@ -1,166 +1,23 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - UserTimeline Interval (sec) - - - 170, 12 - - - Timeline Fetching Interval (sec.) - - - 358, 12 - - - Because "Post && fetch" is enabled, the API for each post consumed. - - - 150, 12 - - - Lists Fetching Interval (sec) - - - 149, 12 - - - Public Search Interval (sec.) - - - 156, 12 - - - Reply Fetching Interval (sec.) - - - 88, 16 - - - Post && fetch - - - 144, 12 - - - DM Fetching Interval (sec.) - - \ No newline at end of file + 88, 16 + Post && fetch + UserTimeline Interval (sec) + 170, 12 + Timeline Fetching Interval (sec.) + 150, 12 + Lists Fetching Interval (sec) + 144, 12 + DM Fetching Interval (sec.) + 156, 12 + Reply Fetching Interval (sec.) + 149, 12 + Public Search Interval (sec.) + 358, 12 + Because "Post && fetch" is enabled, the API for each post consumed. + diff --git a/OpenTween/Setting/Panel/GetPeriodPanel.resx b/OpenTween/Setting/Panel/GetPeriodPanel.resx index dae4ec5e5..83e1391f6 100644 --- a/OpenTween/Setting/Panel/GetPeriodPanel.resx +++ b/OpenTween/Setting/Panel/GetPeriodPanel.resx @@ -1,519 +1,142 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 23, 182 - - - 144, 12 - - - 34 - - - UserTimeline更新間隔(秒) - - - Label21 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - Disable - - - 259, 179 - - - 65, 19 - - - 35 - - - UserTimelinePeriod - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Disable - - - 259, 17 - - - 65, 19 - - - 24 - - - TimelinePeriod - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - NoControl - - - 23, 20 - - - 130, 12 - - - 23 - - - タイムライン更新間隔(秒) - - - Label3 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 279 - - - 285, 12 - - - 36 - - - 投稿時取得が有効のため、投稿のたびにAPIを消費します。 - - - LabelPostAndGet - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 23, 153 - - - 102, 12 - - - 32 - - - Lists更新間隔(秒) - - - Label33 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - Disable - - - 259, 150 - - - 65, 19 - - - 33 - - - ListsPeriod - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - NoControl - - - 23, 124 - - - 137, 12 - - - 30 - - - Twitter検索更新間隔(秒) - - - Label7 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - Disable - - - 259, 121 - - - 65, 19 - - - 31 - - - PubSearchPeriod - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - True - - - NoControl - - - 23, 66 - - - 123, 12 - - - 26 - - - Mentions更新間隔(秒) - - - Label69 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - Disable - - - 259, 63 - - - 65, 19 - - - 27 - - - ReplyPeriod - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - True - - - NoControl - - - 45, 38 - - - 84, 16 - - - 25 - - - 投稿時取得 - - - CheckPostAndGet - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - True - - - NoControl - - - 23, 95 - - - 94, 12 - - - 28 - - - DM更新間隔(秒) - - - Label5 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 12 - - - Disable - - - 259, 92 - - - 65, 19 - - - 29 - - - DMPeriod - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 13 - - - True - - - 96, 96 - - - GetPeriodPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + GetPeriodPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null + CheckPostAndGet + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + DMPeriod + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + Label21 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + Label3 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + Label33 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + Label5 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + Label69 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + Label7 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + LabelPostAndGet + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + ListsPeriod + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + PubSearchPeriod + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + ReplyPeriod + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + TimelinePeriod + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + UserTimelinePeriod + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + True + NoControl + 45, 38 + 84, 16 + 25 + 投稿時取得 + Disable + 259, 92 + 65, 19 + 29 + True + NoControl + 23, 182 + 144, 12 + 34 + UserTimeline更新間隔(秒) + True + NoControl + 23, 20 + 130, 12 + 23 + タイムライン更新間隔(秒) + True + NoControl + 23, 153 + 102, 12 + 32 + Lists更新間隔(秒) + True + NoControl + 23, 95 + 94, 12 + 28 + DM更新間隔(秒) + True + NoControl + 23, 66 + 123, 12 + 26 + Mentions更新間隔(秒) + True + NoControl + 23, 124 + 137, 12 + 30 + Twitter検索更新間隔(秒) + True + NoControl + 23, 279 + 285, 12 + 36 + 投稿時取得が有効のため、投稿のたびにAPIを消費します。 + Disable + 259, 150 + 65, 19 + 33 + Disable + 259, 121 + 65, 19 + 31 + Disable + 259, 63 + 65, 19 + 27 + Disable + 259, 17 + 65, 19 + 24 + Disable + 259, 179 + 65, 19 + 35 + diff --git a/OpenTween/Setting/Panel/NotifyPanel.en.resx b/OpenTween/Setting/Panel/NotifyPanel.en.resx index 1af7de150..cabc33e77 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.en.resx +++ b/OpenTween/Setting/Panel/NotifyPanel.en.resx @@ -1,120 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file + diff --git a/OpenTween/Setting/Panel/NotifyPanel.resx b/OpenTween/Setting/Panel/NotifyPanel.resx index 0510b4380..f035d0984 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.resx +++ b/OpenTween/Setting/Panel/NotifyPanel.resx @@ -1,133 +1,12 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - - 96, 96 - - - NotifyPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + NotifyPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null + diff --git a/OpenTween/Setting/Panel/PreviewPanel.en.resx b/OpenTween/Setting/Panel/PreviewPanel.en.resx index 99402d649..a8233b161 100644 --- a/OpenTween/Setting/Panel/PreviewPanel.en.resx +++ b/OpenTween/Setting/Panel/PreviewPanel.en.resx @@ -1,305 +1,72 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 224, 12 - - - * Require Growl Connector Libralies(DLLs) - - - Require to get DLLs below and to copy to the path same as Tween.exe. + + 97, 16 + Always on top + + 293, 16 + Popup balloon only at the minimization or iconization + + 278, 16 + Show username in application titlebar and balloon + + 232, 16 + Use monospace font in tweet detail area + + 138, 16 + Show image thumbnail + + 278, 16 + Locate tweet detail and input area at the bottom + + 180, 16 + Blink window mentions arrived + + 210, 16 + Show icon on tab has unread tweets + + None + User ID + Nickname + + None + Program Version + Latest your post + unread @reply items + unread items + unread items(unread @reply items) + unread items/all items + Count of Status/Follow/Follower + + 194, 16 + Use 'Growl for Windows' to notify + + 103, 12 + Username in popup + + + 224, 12 + * Require Growl Connector Libralies(DLLs) + Require to get DLLs below and to copy to the path same as Tween.exe. Growl.Connector.DLL Growl.CoreLibrary.DLL These are contained in 'Growl_NET_Connector_SDK.zip'. -This file is released for developers in Growl for Windows web site. - - - 194, 16 - - - Use 'Growl for Windows' to notify - - - - - - Don't notify - - - Change icon - - - Change icon&blink - - - - - - 188, 12 - - - Tasktray icon with unread mentions - - - - - - 180, 16 - - - Blink window mentions arrived - - - - - - 210, 16 - - - Show icon on tab has unread tweets - - - - - - 138, 16 - - - Show image thumbnail - - - - - - - - - - - - - - - 97, 16 - - - Always on top - - - - - - 232, 16 - - - Use monospace font in tweet detail area - - - - - - 293, 16 - - - Popup balloon only at the minimization or iconization - - - - - - 103, 12 - - - Username in popup - - - - - - None - - - Program Version - - - Latest your post - - - unread @reply items - - - unread items - - - unread items(unread @reply items) - - - unread items/all items - - - Count of Status/Follow/Follower - - - - - - 65, 12 - - - Title format - - - - - - None - - - User ID - - - Nickname - - - - - - 278, 16 - - - Show username in application titlebar and balloon - - - - - - 278, 16 - - - Locate tweet detail and input area at the bottom - - - - - - - - \ No newline at end of file +This file is released for developers in Growl for Windows web site. + 65, 12 + Title format + + 188, 12 + Tasktray icon with unread mentions + + + + Don't notify + Change icon + Change icon&blink + + diff --git a/OpenTween/Setting/Panel/PreviewPanel.resx b/OpenTween/Setting/Panel/PreviewPanel.resx index 725c5a0db..ea8ffeeb7 100644 --- a/OpenTween/Setting/Panel/PreviewPanel.resx +++ b/OpenTween/Setting/Panel/PreviewPanel.resx @@ -1,738 +1,217 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 236, 330 - - - 223, 12 - - - 37 - - - ※別途DLLが必要です(マウスオーバーで表示) - - - 17, 17 - - - Growl for Windowsの開発者向けに公開されている、 + 96, 96 + True + 20, 10, 20, 10 + PreviewPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + CheckAlwaysTop + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + CheckBalloonLimit + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + CheckDispUsername + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 17 + CheckMonospace + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + CheckPreviewEnable + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + CheckStatusAreaAtBottom + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 18 + ChkNewMentionsBlink + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + chkTabIconDisp + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + cmbNameBalloon + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 16 + ComboDispTitle + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + IsNotifyUseGrowlCheckBox + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + Label10 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + Label13 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + Label2 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + Label45 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + Label72 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + Label81 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + LanguageCombo + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + ReplyIconStateCombo + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + toolTip + System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + True + NoControl + 23, 275 + 133, 16 + 32 + 常に最前面に表示する + True + NoControl + 23, 67 + 249, 16 + 22 + 画面最小化・アイコン時のみバルーンを表示する + True + NoControl + 23, 42 + 235, 16 + 21 + タイトルバーとツールチップにユーザー名を表示 + True + NoControl + 23, 250 + 343, 16 + 31 + 発言詳細を等幅フォントで表示(AA対応、フォント適用不具合あり) + True + NoControl + 23, 200 + 243, 16 + 29 + 画像リンクがあった場合にサムネイルを表示する + True + NoControl + 23, 225 + 257, 16 + 30 + 発言詳細部・入力欄を発言一覧の下に配置する + True + NoControl + 23, 175 + 256, 16 + 28 + Mentionsの新着があるときにウインドウを点滅する + True + NoControl + 23, 121 + 161, 16 + 25 + タブに未読アイコンを表示する + なし + ユーザーID + ニックネーム + 276, 13 + 136, 20 + 20 + (なし) + バージョン + 最終発言 + @未読数 + 未読数 + 未読数(@未読数) + 全未読/全発言数 + 発言数/フォロー数/フォロワー数 + 276, 92 + 197, 20 + 24 + True + NoControl + 23, 329 + 119, 16 + 36 + 通知にGrowlを使用 + True + NoControl + 23, 16 + 130, 12 + 19 + 新着バルーンのユーザー名 + True + NoControl + 23, 303 + 53, 12 + 33 + Language + True + NoControl + 236, 330 + 223, 12 + 37 + ※別途DLLが必要です(マウスオーバーで表示) + Growl for Windowsの開発者向けに公開されている、 Growl_NET_Connector_SDK.zipに同梱の次のDLLが必要です Growl.Connector.DLL -Growl.CoreLibrary.DLL - - - Label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 23, 329 - - - 119, 16 - - - 36 - - - 通知にGrowlを使用 - - - IsNotifyUseGrowlCheckBox - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - 通知なし - - - アイコン変更 - - - アイコン変更&点滅 - - - 276, 146 - - - 136, 20 - - - 27 - - - ReplyIconStateCombo - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - NoControl - - - 23, 149 - - - 134, 12 - - - 26 - - - 未読Mentions通知アイコン - - - Label72 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 175 - - - 256, 16 - - - 28 - - - Mentionsの新着があるときにウインドウを点滅する - - - ChkNewMentionsBlink - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 23, 121 - - - 161, 16 - - - 25 - - - タブに未読アイコンを表示する - - - chkTabIconDisp - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 23, 200 - - - 243, 16 - - - 29 - - - 画像リンクがあった場合にサムネイルを表示する - - - CheckPreviewEnable - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - NoControl - - - 92, 303 - - - 115, 12 - - - 34 - - - Apply after restarting - - - Label81 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - OS Default - - - Japanese - - - English - - - 276, 300 - - - 136, 20 - - - 35 - - - LanguageCombo - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - True - - - NoControl - - - 23, 303 - - - 53, 12 - - - 33 - - - Language - - - Label13 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - True - - - NoControl - - - 23, 275 - - - 133, 16 - - - 32 - - - 常に最前面に表示する - - - CheckAlwaysTop - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - True - - - NoControl - - - 23, 250 - - - 343, 16 - - - 31 - - - 発言詳細を等幅フォントで表示(AA対応、フォント適用不具合あり) - - - CheckMonospace - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - True - - - NoControl - - - 23, 67 - - - 249, 16 - - - 22 - - - 画面最小化・アイコン時のみバルーンを表示する - - - CheckBalloonLimit - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 12 - - - True - - - NoControl - - - 23, 16 - - - 130, 12 - - - 19 - - - 新着バルーンのユーザー名 - - - Label10 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 13 - - - (なし) - - - バージョン - - - 最終発言 - - - @未読数 - - - 未読数 - - - 未読数(@未読数) - - - 全未読/全発言数 - - - 発言数/フォロー数/フォロワー数 - - - 276, 92 - - - 197, 20 - - - 24 - - - ComboDispTitle - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 14 - - - True - - - NoControl - - - 23, 95 - - - 60, 12 - - - 23 - - - タイトルバー - - - Label45 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 15 - - - なし - - - ユーザーID - - - ニックネーム - - - 276, 13 - - - 136, 20 - - - 20 - - - cmbNameBalloon - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 16 - - - True - - - NoControl - - - 23, 42 - - - 235, 16 - - - 21 - - - タイトルバーとツールチップにユーザー名を表示 - - - CheckDispUsername - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 17 - - - True - - - NoControl - - - 23, 225 - - - 257, 16 - - - 30 - - - 発言詳細部・入力欄を発言一覧の下に配置する - - - CheckStatusAreaAtBottom - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 18 - - - True - - - 96, 96 - - - 20, 10, 20, 10 - - - toolTip - - - System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - PreviewPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file +Growl.CoreLibrary.DLL + True + NoControl + 23, 95 + 60, 12 + 23 + タイトルバー + True + NoControl + 23, 149 + 134, 12 + 26 + 未読Mentions通知アイコン + True + NoControl + 92, 303 + 115, 12 + 34 + Apply after restarting + OS Default + Japanese + English + 276, 300 + 136, 20 + 35 + 通知なし + アイコン変更 + アイコン変更&点滅 + 276, 146 + 136, 20 + 27 + 17, 17 + diff --git a/OpenTween/Setting/Panel/ProxyPanel.en.resx b/OpenTween/Setting/Panel/ProxyPanel.en.resx index f7deb663e..15c79536f 100644 --- a/OpenTween/Setting/Panel/ProxyPanel.en.resx +++ b/OpenTween/Setting/Panel/ProxyPanel.en.resx @@ -1,169 +1,24 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 320, 12 - - - Keep credential empty if the proxy server don't need to log in - - - 73, 16 - - - Don't Use - - - 54, 12 - - - Pass&word - - - 200, 16 - - - Refer Settings of Internet Explorer - - - 80, 16 - - - Use Below: - - - 56, 12 - - - &Username - - - 62, 12 - - - Pro&xy Host - - - 26, 12 - - - &Port - - \ No newline at end of file + 320, 12 + Keep credential empty if the proxy server don't need to log in + 62, 12 + Pro&xy Host + 54, 12 + Pass&word + 26, 12 + &Port + 56, 12 + &Username + 200, 16 + Refer Settings of Internet Explorer + 73, 16 + Don't Use + 80, 16 + Use Below: + diff --git a/OpenTween/Setting/Panel/ProxyPanel.resx b/OpenTween/Setting/Panel/ProxyPanel.resx index 50313796e..b75526061 100644 --- a/OpenTween/Setting/Panel/ProxyPanel.resx +++ b/OpenTween/Setting/Panel/ProxyPanel.resx @@ -1,462 +1,123 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 50, 153 - - - 314, 12 - - - 23 - - - ※認証が不要な場合は、ユーザ名とパスワードは空にしてください。 - - - Label55 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - 356, 127 - - - 130, 19 - - - 22 - - - TextProxyPassword - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - NoControl - - - 23, 23 - - - 76, 16 - - - 12 - - - 使用しない - - - RadioProxyNone - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - NoControl - - - 275, 130 - - - 69, 12 - - - 21 - - - パスワード(&W) - - - LabelProxyPassword - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 48 - - - 190, 16 - - - 13 - - - InternetExplorerの設定を使用する - - - RadioProxyIE - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - 124, 127 - - - 130, 19 - - - 20 - - - TextProxyUser - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 23, 73 - - - 66, 16 - - - 14 - - - 指定する - - - RadioProxySpecified - - - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - NoControl - - - 50, 130 - - - 63, 12 - - - 19 - - - ユーザ名(&U) - - - LabelProxyUser - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - True - - - NoControl - - - 50, 101 - - - 58, 12 - - - 15 - - - プロキシ(&X) - - - LabelProxyAddress - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - Disable - - - 356, 98 - - - 73, 19 - - - 18 - - - TextProxyPort - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - 124, 98 - - - 130, 19 - - - 16 - - - TextProxyAddress - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - True - - - NoControl - - - 275, 101 - - - 48, 12 - - - 17 - - - ポート(&P) - - - LabelProxyPort - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - True - - - 96, 96 - - - ProxyPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + ProxyPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + Label55 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + LabelProxyAddress + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + LabelProxyPassword + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + LabelProxyPort + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + LabelProxyUser + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + RadioProxyIE + $this + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + RadioProxyNone + $this + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + RadioProxySpecified + $this + System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + TextProxyAddress + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + TextProxyPassword + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + TextProxyPort + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + TextProxyUser + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + True + NoControl + 50, 153 + 314, 12 + 23 + ※認証が不要な場合は、ユーザ名とパスワードは空にしてください。 + True + NoControl + 50, 101 + 58, 12 + 15 + プロキシ(&X) + True + NoControl + 275, 130 + 69, 12 + 21 + パスワード(&W) + True + NoControl + 275, 101 + 48, 12 + 17 + ポート(&P) + True + NoControl + 50, 130 + 63, 12 + 19 + ユーザ名(&U) + True + NoControl + 23, 48 + 190, 16 + 13 + InternetExplorerの設定を使用する + True + NoControl + 23, 23 + 76, 16 + 12 + 使用しない + True + NoControl + 23, 73 + 66, 16 + 14 + 指定する + 124, 98 + 130, 19 + 16 + 356, 127 + 130, 19 + 22 + Disable + 356, 98 + 73, 19 + 18 + 124, 127 + 130, 19 + 20 + diff --git a/OpenTween/Setting/Panel/ShortUrlPanel.en.resx b/OpenTween/Setting/Panel/ShortUrlPanel.en.resx index 2ecd57d18..81c9bc4fb 100644 --- a/OpenTween/Setting/Panel/ShortUrlPanel.en.resx +++ b/OpenTween/Setting/Panel/ShortUrlPanel.en.resx @@ -1,154 +1,19 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 91, 16 - - - t.co wrapping - - - 145, 16 - - - Resolve shortend URLs - - - 205, 16 - - - Auto shorten Urls in posting status - - - 149, 12 - - - Primary URLshorten service - - - 108, 12 - - - Bit.ly Access Token - - - Authorize - - \ No newline at end of file + Authorize + 205, 16 + Auto shorten Urls in posting status + 145, 16 + Resolve shortend URLs + 149, 12 + Primary URLshorten service + 108, 12 + Bit.ly Access Token + 91, 16 + t.co wrapping + diff --git a/OpenTween/Setting/Panel/ShortUrlPanel.resx b/OpenTween/Setting/Panel/ShortUrlPanel.resx index 41f6b3f23..d4a9b05ac 100644 --- a/OpenTween/Setting/Panel/ShortUrlPanel.resx +++ b/OpenTween/Setting/Panel/ShortUrlPanel.resx @@ -1,375 +1,94 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 40, 73 - - - 95, 16 - - - 2 - - - t.coで短縮する - - - False - - - ShortenTcoCheck - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 23, 23 - - - 122, 16 - - - 0 - - - 短縮URLを解決する - - - CheckTinyURL - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - 249, 131 - - - 173, 19 - - - 6 - - - TextBitlyAccessToken - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - NoControl - - - 23, 48 - - - 242, 16 - - - 1 - - - 入力欄のURLを投稿する際に自動で短縮する - - - False - - - CheckAutoConvertUrl - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 101 - - - 154, 12 - - - 3 - - - URL自動短縮で優先的に使用 - - - Label71 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - tinyurl - - - is.gd - - - twurl.nl - - - bit.ly - - - j.mp - - - ux.nu - - - 249, 98 - - - 246, 20 - - - 4 - - - ComboBoxAutoShortUrlFirst - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 23, 134 - - - 106, 12 - - - 5 - - - Bit.ly アクセストークン - - - Label77 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - 429, 129 - - - 67, 23 - - - 7 - - - 認可 - - - ButtonBitlyAuthorize - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - 96, 96 - - - ShortUrlPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + ShortUrlPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + ButtonBitlyAuthorize + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + CheckAutoConvertUrl + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + CheckTinyURL + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + ComboBoxAutoShortUrlFirst + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + Label71 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + Label77 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + ShortenTcoCheck + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TextBitlyAccessToken + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + 429, 129 + 67, 23 + 7 + 認可 + True + NoControl + 23, 48 + 242, 16 + 1 + 入力欄のURLを投稿する際に自動で短縮する + False + True + NoControl + 23, 23 + 122, 16 + 0 + 短縮URLを解決する + tinyurl + is.gd + twurl.nl + bit.ly + j.mp + ux.nu + 249, 98 + 246, 20 + 4 + True + NoControl + 23, 101 + 154, 12 + 3 + URL自動短縮で優先的に使用 + True + NoControl + 23, 134 + 106, 12 + 5 + Bit.ly アクセストークン + True + NoControl + 40, 73 + 95, 16 + 2 + t.coで短縮する + False + 249, 131 + 173, 19 + 6 + diff --git a/OpenTween/Setting/Panel/StartupPanel.en.resx b/OpenTween/Setting/Panel/StartupPanel.en.resx index c2c11df8d..e3a17874b 100644 --- a/OpenTween/Setting/Panel/StartupPanel.en.resx +++ b/OpenTween/Setting/Panel/StartupPanel.en.resx @@ -1,145 +1,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 91, 16 - - - Mark as read - - - 123, 16 - - - Fetch followers list - - - 121, 16 - - - Check new version - - - 105, 16 - - - Fetch Favorites - - \ No newline at end of file + 123, 16 + Fetch followers list + 121, 16 + Check new version + 105, 16 + Fetch Favorites + 91, 16 + Mark as read + diff --git a/OpenTween/Setting/Panel/StartupPanel.resx b/OpenTween/Setting/Panel/StartupPanel.resx index cb926c2d4..bba2b387f 100644 --- a/OpenTween/Setting/Panel/StartupPanel.resx +++ b/OpenTween/Setting/Panel/StartupPanel.resx @@ -1,255 +1,54 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 2 - - - $this - - - 3 - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 7 - - - - NoControl - - - True - - - 最新版のチェックをする - - - 片思いユーザーリストを取得する - - - - 166, 16 - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - 4 - - - StartupPanel - - - 1 - - - 23, 98 - - - 23, 48 - - - StartupReaded - - - chkGetFav - - - 129, 16 - - - CheckStartupFollowers - - - Favoritesを取得する - - - 23, 23 - - - True - - - NoControl - - - CheckStartupVersion - - - 6 - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 読み込んだポストを既読にする - - - 174, 16 - - - True - - - 124, 16 - - - $this - - - True - - - 23, 73 - - - NoControl - - - $this - - - 0 - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 96, 96 - - - NoControl - - - 5 - - - $this - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - \ No newline at end of file + 96, 96 + True + StartupPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + CheckStartupFollowers + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + CheckStartupVersion + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + chkGetFav + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + StartupReaded + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + True + NoControl + 23, 73 + 174, 16 + 6 + 片思いユーザーリストを取得する + True + NoControl + 23, 48 + 129, 16 + 5 + 最新版のチェックをする + True + NoControl + 23, 98 + 124, 16 + 7 + Favoritesを取得する + True + NoControl + 23, 23 + 166, 16 + 4 + 読み込んだポストを既読にする + diff --git a/OpenTween/Setting/Panel/TweetActPanel.en.resx b/OpenTween/Setting/Panel/TweetActPanel.en.resx index e8dee5ddd..9b8cc5bd5 100644 --- a/OpenTween/Setting/Panel/TweetActPanel.en.resx +++ b/OpenTween/Setting/Panel/TweetActPanel.en.resx @@ -1,169 +1,24 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 213, 16 - - - Use Hashtag supplementary function - - - 188, 16 - - - Use @id supplementary function - - - 50, 12 - - - Post key - - - 239, 16 - - - Bypass confirm dialog at posting Retweet - - - 38, 12 - - - Footer - - - 151, 16 - - - Use Default [TWNvNNN] - - - 405, 16 - - - Avoid converting to JPEG when posting PNG images (pic.twitter.com only) - - - 332, 12 - - - It rewrites the alpha value of upper left 1px of the image to 254 - - \ No newline at end of file + 405, 16 + Avoid converting to JPEG when posting PNG images (pic.twitter.com only) + 188, 16 + Use @id supplementary function + 213, 16 + Use Hashtag supplementary function + 239, 16 + Bypass confirm dialog at posting Retweet + 151, 16 + Use Default [TWNvNNN] + 38, 12 + Footer + 50, 12 + Post key + 332, 12 + It rewrites the alpha value of upper left 1px of the image to 254 + diff --git a/OpenTween/Setting/Panel/TweetActPanel.resx b/OpenTween/Setting/Panel/TweetActPanel.resx index 2a8f8e119..6da866ed5 100644 --- a/OpenTween/Setting/Panel/TweetActPanel.resx +++ b/OpenTween/Setting/Panel/TweetActPanel.resx @@ -1,426 +1,111 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 23, 156 - - - 157, 16 - - - 23 - - - #タグの入力補助を使用する - - - CheckHashSupple - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 23, 131 - - - 153, 16 - - - 22 - - - @IDの入力補助を使用する - - - CheckAtIdSupple - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Enter - - - Ctrl+Enter - - - Shift+Enter - - - 218, 23 - - - 246, 20 - - - 17 - - - ComboBoxPostKeySelect - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - NoControl - - - 23, 26 - - - 137, 12 - - - 16 - - - POSTキー(デフォルトEnter) - - - Label27 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 23, 52 - - - 165, 16 - - - 18 - - - 公式RTする際に確認をしない - - - CheckRetweetNoConfirm - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - True - - - NoControl - - - 23, 78 - - - 107, 12 - - - 19 - - - フッター(文末に付加) - - - Label12 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 218, 77 - - - 195, 16 - - - 20 - - - 推奨フッターを使用する[TWNv○○] - - - CheckUseRecommendStatus - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - 218, 102 - - - 232, 19 - - - 21 - - - StatusText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - True - - - 23, 178 - - - 361, 16 - - - 24 - - - PNG画像の投稿時にJPEGへの変換を回避する (pic.twitter.com のみ) - - - CheckAlphaPNGWorkaround - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - True - - - NoControl - - - 40, 200 - - - 3, 3, 3, 3 - - - 357, 12 - - - 25 - - - ※投稿する画像の左上1pxのアルファ値を254に書き換えることで回避します - - - label3 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - True - - - 96, 96 - - - TweetActPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + TweetActPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + CheckAlphaPNGWorkaround + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + CheckAtIdSupple + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + CheckHashSupple + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + CheckRetweetNoConfirm + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + CheckUseRecommendStatus + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + ComboBoxPostKeySelect + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Label12 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + Label27 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + label3 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + StatusText + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + True + 23, 178 + 361, 16 + 24 + PNG画像の投稿時にJPEGへの変換を回避する (pic.twitter.com のみ) + True + NoControl + 23, 131 + 153, 16 + 22 + @IDの入力補助を使用する + True + NoControl + 23, 156 + 157, 16 + 23 + #タグの入力補助を使用する + True + NoControl + 23, 52 + 165, 16 + 18 + 公式RTする際に確認をしない + True + NoControl + 218, 77 + 195, 16 + 20 + 推奨フッターを使用する[TWNv○○] + Enter + Ctrl+Enter + Shift+Enter + 218, 23 + 246, 20 + 17 + True + NoControl + 23, 78 + 107, 12 + 19 + フッター(文末に付加) + True + NoControl + 23, 26 + 137, 12 + 16 + POSTキー(デフォルトEnter) + True + NoControl + 40, 200 + 3, 3, 3, 3 + 357, 12 + 25 + ※投稿する画像の左上1pxのアルファ値を254に書き換えることで回避します + 218, 102 + 232, 19 + 21 + diff --git a/OpenTween/Setting/Panel/TweetPrvPanel.en.resx b/OpenTween/Setting/Panel/TweetPrvPanel.en.resx index 42a8c5eb6..ee5955c86 100644 --- a/OpenTween/Setting/Panel/TweetPrvPanel.en.resx +++ b/OpenTween/Setting/Panel/TweetPrvPanel.en.resx @@ -1,175 +1,26 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 127, 16 - - - Include RTs in Lists - - - 151, 16 - - - Hide duplicated retweets - - - 105, 12 - - - Date Format in List - - - 162, 12 - - - Icon size in List (16 in default) - - - 202, 16 - - - View tabs at the bottom of the list - - - 102, 16 - - - Lock sort order - - - 125, 16 - - - Show separator line - - - 393, 16 - - - Enable unread style(font and color). (Unread can be found by star mark) - - - 379, 16 - - - Colorize one way love user's tweets (following and not followed user) - - \ No newline at end of file + 125, 16 + Show separator line + 102, 16 + Lock sort order + 202, 16 + View tabs at the bottom of the list + 393, 16 + Enable unread style(font and color). (Unread can be found by star mark) + 151, 16 + Hide duplicated retweets + 127, 16 + Include RTs in Lists + 162, 12 + Icon size in List (16 in default) + 105, 12 + Date Format in List + 379, 16 + Colorize one way love user's tweets (following and not followed user) + diff --git a/OpenTween/Setting/Panel/TweetPrvPanel.resx b/OpenTween/Setting/Panel/TweetPrvPanel.resx index 059a59b6a..0c276eacf 100644 --- a/OpenTween/Setting/Panel/TweetPrvPanel.resx +++ b/OpenTween/Setting/Panel/TweetPrvPanel.resx @@ -1,579 +1,162 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - NoControl - - - - 23, 98 - - - 189, 16 - - - 31 - - - Listの発言取得に公式RTを含める - - - IsListsIncludeRtsCheckBox - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - NoControl - - - 23, 48 - - - 167, 16 - - - 19 - - - 重複した公式RTを表示しない - - - HideDuplicatedRetweetsCheck - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - NoControl - - - 303, 149 - - - 44, 12 - - - 24 - - - Label63 - - - LabelDateTimeFormatApplied - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - NoControl - - - 241, 149 - - - 44, 12 - - - 23 - - - Sample: - - - Label62 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - yyyy/MM/dd H:mm:ss - - - yy/M/d H:mm:ss - - - H:mm:ss yy/M/d - - - M/d H:mm:ss - - - M/d H:mm - - - H:mm:ss M/d - - - H:mm:ss - - - H:mm - - - tt h:mm - - - M/d tt h:mm:ss - - - M/d tt h:mm - - - 244, 123 - - - 193, 20 - - - 22 - - - CmbDateTimeFormat - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - True - - - NoControl - - - 23, 126 - - - 113, 12 - - - 21 - - - リストの日時フォーマット - - - Label23 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - True - - - NoControl - - - 23, 175 - - - 163, 12 - - - 25 - - - リストのアイコンサイズ(初期値16) - - - Label11 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - none - - - 16*16 - - - 24*24 - - - 48*48 - - - 48*48(2Column) - - - 284, 172 - - - 163, 20 - - - 27 - - - IconSize - - - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - False - - - 244, 172 - - - 34, 19 - - - 26 - - - TextBox3 - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - True - - - NoControl - - - 23, 266 - - - 148, 16 - - - 32 - - - タブを一覧の下に表示する - - - CheckViewTabBottom - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - True - - - NoControl - - - 23, 241 - - - 203, 16 - - - 30 - - - ソート順を変更できないようにロックする - - - CheckSortOrderLock - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - True - - - NoControl - - - 23, 216 - - - 154, 16 - - - 29 - - - リストの区切り線を表示する - - - CheckShowGrid - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 12 - - - True - - - NoControl - - - 23, 73 - - - 226, 16 - - - 20 - - - 未読ポストのフォントと色を変更する(低速) - - - chkUnreadStyle - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 13 - - - True - - - NoControl - - - 23, 23 - - - 162, 16 - - - 18 - - - 片思いを色分けして表示する - - - OneWayLv - - - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 14 - - - True - - - 96, 96 - - - TweetPrvPanel - - - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + True + TweetPrvPanel + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + CheckShowGrid + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + CheckSortOrderLock + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + CheckViewTabBottom + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + chkUnreadStyle + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + CmbDateTimeFormat + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + HideDuplicatedRetweetsCheck + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + IconSize + $this + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + IsListsIncludeRtsCheckBox + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + Label11 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + Label23 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + Label62 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + LabelDateTimeFormatApplied + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + OneWayLv + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + TextBox3 + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + True + NoControl + 23, 216 + 154, 16 + 29 + リストの区切り線を表示する + True + NoControl + 23, 241 + 203, 16 + 30 + ソート順を変更できないようにロックする + True + NoControl + 23, 266 + 148, 16 + 32 + タブを一覧の下に表示する + True + NoControl + 23, 73 + 226, 16 + 20 + 未読ポストのフォントと色を変更する(低速) + yyyy/MM/dd H:mm:ss + yy/M/d H:mm:ss + M/d tt h:mm + H:mm:ss yy/M/d + M/d H:mm:ss + M/d H:mm + H:mm:ss M/d + H:mm:ss + H:mm + tt h:mm + M/d tt h:mm:ss + 244, 123 + 193, 20 + 22 + True + NoControl + 23, 48 + 167, 16 + 19 + 重複した公式RTを表示しない + none + 16*16 + 24*24 + 48*48 + 48*48(2Column) + 284, 172 + 163, 20 + 27 + True + NoControl + 23, 98 + 189, 16 + 31 + Listの発言取得に公式RTを含める + True + NoControl + 23, 175 + 163, 12 + 25 + リストのアイコンサイズ(初期値16) + True + NoControl + 23, 126 + 113, 12 + 21 + リストの日時フォーマット + True + NoControl + 241, 149 + 44, 12 + 23 + Sample: + True + NoControl + 303, 149 + 44, 12 + 24 + Label63 + True + NoControl + 23, 23 + 162, 16 + 18 + 片思いを色分けして表示する + False + 244, 172 + 34, 19 + 26 + diff --git a/OpenTween/TabsDialog.en.resx b/OpenTween/TabsDialog.en.resx index 3542de762..cfb27f483 100644 --- a/OpenTween/TabsDialog.en.resx +++ b/OpenTween/TabsDialog.en.resx @@ -1,129 +1,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Cancel - - - (New Tab) - - - Select Tab - - \ No newline at end of file + Select Tab + Cancel + (New Tab) + diff --git a/OpenTween/TabsDialog.resx b/OpenTween/TabsDialog.resx index 26ac2cfff..bffb45c9e 100644 --- a/OpenTween/TabsDialog.resx +++ b/OpenTween/TabsDialog.resx @@ -1,219 +1,42 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - False - - - - 10, 104 - - - 71, 21 - - - 0 - - - OK - - - OK_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - 88, 104 - - - 71, 21 - - - 1 - - - キャンセル - - - Cancel_Button - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - 12 - - - 10, 10 - - - 150, 88 - - - 0 - - - TabList - - - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - 96, 96 - - - 170, 135 - - - CenterParent - - - タブ選択 - - - TabsDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 170, 135 + True + CenterParent + タブ選択 + TabsDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + Cancel_Button + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + OK_Button + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + TabList + $this + System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + 88, 104 + 71, 21 + 1 + キャンセル + False + 10, 104 + 71, 21 + 0 + OK + 12 + 10, 10 + 150, 88 + 0 + diff --git a/OpenTween/Tween.en.resx b/OpenTween/Tween.en.resx index 819f3d9b5..60d9549b5 100644 --- a/OpenTween/Tween.en.resx +++ b/OpenTween/Tween.en.resx @@ -1,194 +1,98 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 410, 23 - - - 445, 24 - - - &Separation of multibyte character string from URL - - - 445, 24 - - - Prevent interpreting text as SMS command - - - 445, 24 - - - &URL is automatically shortened - - - 445, 24 - - - &Convert IdeographicSpace to Space - - - 445, 24 - - - Input field is &Multiline - - - 445, 24 - - - Left focus in input box after posting - - - 442, 6 - - - 445, 24 - - - &Pick a media file - - - 442, 6 - - - 445, 24 - - - &Toggle Hashtag - - - 445, 24 - - - Hashtag &Manager - - - 446, 232 - - - - - - + 574, 382 + + 278, 24 + &About %AppName%... + 247, 24 + Create &New Tab... + 278, 24 + Twitter API Usage + 218, 24 + 347, 24 + Change Unread state ... + 247, 24 + Clear Posts in This Tab + 248, 24 + &Clear posts in this tab + 248, 166 + + 259, 556 + + 446, 232 + + 248, 251 + + 320, 24 + &Copy (STOT-style) + 320, 24 + Copy (&Status URL) + 320, 24 + Copy(Usern&ame) + 118, 22 + &ID + 347, 24 + &Filter by ... + 118, 22 + &Source + 118, 22 + Post(&N) + 248, 24 + Create &New Tab... + 278, 24 + 258, 24 + &Delete + 247, 24 + &Delete This Tab + 248, 24 + &Delete this tab + 347, 24 + &Delete your tweet/DM + 347, 24 + Send D&M + 258, 24 + Send D&M + 248, 24 + Edit &Filtering rules... + 242, 24 + E&xit + 247, 24 + E&xit + 258, 24 + Mark &Favorite + 347, 24 + Favorite(&S) + 258, 24 + Fav+Retweet + 347, 24 + Fav+Retweet + 258, 24 + Fav+Retweet(Unofficial) + 347, 24 + Fav+Retweet(Unofficial) + 258, 24 + Unmark Favorite + 247, 24 + Edit &Filtering Rules... + 334, 22 + Left focus in input box after posting + 445, 24 + Left focus in input box after posting + 294, 24 + &Follow + 294, 24 + S&how Friendship + 334, 22 + &Hashtag Manager + 445, 24 + Hashtag &Manager + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6 JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACA0lEQVQ4T6WS60uTYRjG94+ElodKEUFR MQ+IKJ5A6YOIRmCsRulgaIJDGSoDzQhFSRQRnRhExL4MMjvQyRObMmcNzyJTxBPaYAQi2eV73TAfBMPI @@ -200,1124 +104,118 @@ 0T9x41rKIwXgqJgxKOZjY7sHhRr41oNhAYQm6ZFu/IbUhx8EcjXZoABczxHntohZM2sstji180+IK+lH VJ5V67pZbMcUPpMdIPAUwN2mZQbrY0k8ozg6v1nEHFvwfyXuDkIS7ykA58zdZqdJ55LwIUfFbjMza6Zt ZqY4JKFcAf7/A04A0AEgNTFacM8AAAAASUVORK5CYII= - - - - 574, 28 - - - - - - - - - PostsListArea - - - 247, 24 - - - Create &New Tab... - - - 247, 24 - - - Rename Tab - - - 244, 6 - - - 247, 24 - - - &Protect Tab - - - 247, 24 - - - Manage Reading (&U) - - - 247, 24 - - - &Enable Alert Popup (&Q) - - - Select a wav file. - - - 244, 6 - - - 247, 24 - - - Edit &Filtering Rules... - - - 244, 6 - - - 247, 24 - - - Clear Posts in This Tab - - - 244, 6 - - - 247, 24 - - - &Delete This Tab - - - 248, 251 - - - - - - 570, 149 - - - - - - 570, 149 - - - - - - 570, 149 - - - - - - - - - PostDetailsArea - - - - - - PostComposeArea - - - 452, 22 - - - PostBodyInput - - - - - - 452, 0 - - - RemainCharacterLength - - - - - - 511, 0 - - - - - - - - - 570, 168 - - - - 141 - - - - - - - - - ThumbnailArea - - - 55, 170 - - - - - - - - - 570, 168 - - - - - - - - - 574, 327 - - - 153 - - - - - - 574, 327 - - - - - - - - - - - - 574, 382 - - - - - - 242, 24 - - - Settings(&O)... - - - Open URL(&L)... - - - 239, 6 - - - 242, 24 - - - &Save to text file - - - 239, 6 - - - 242, 24 - - - Enable Alert popup(&Q) - - - 242, 24 - - - Enable Sounds - - - 242, 24 - - - Stick &List - - - 239, 6 - - - 242, 24 - - - Stop Refresh - - - 239, 6 - - - 242, 24 - - - &Restart - - - 242, 24 - - - E&xit - - - 47, 23 - - - &File - - - 320, 24 - - - Undo remove tab - - - 317, 6 - - - 320, 24 - - - &Copy (STOT-style) - - - 320, 24 - - - Copy (&Status URL) - - - 320, 24 - - - Copy(Usern&ame) - - - 317, 6 - - - 320, 24 - - - &Find... - - - 320, 24 - - - Find Ne&xt - - - 320, 24 - - - Find &Previous - - - 317, 6 - - - 320, 24 - - - Input search &Query - - - 49, 23 - - - &Edit - - - 347, 24 - - - @&Reply - - - 347, 24 - - - @R&eply All - - - 347, 24 - - - Send D&M - - - 347, 24 - - - 347, 24 - - - 347, 24 - - - 344, 6 - - - 347, 24 - - - Favorite(&S) - - - 347, 24 - - - Fav+Retweet - - - 347, 24 - - - Fav+Retweet(Unofficial) - - - 347, 24 - - - Unfavorite(&V) - - - 344, 6 - - - 347, 24 - - - User &Profile - - - 347, 24 - - - Related Posts (&G) - - - 347, 24 - - - User's updates - - - 306, 24 - - - &Home - - - 306, 24 - - - Favorites(&G) - - - 306, 24 - - - Status(&O) - - - 306, 24 - - - Reply to(&I) - - - 306, 24 - - - Referred &Urls - - - 306, 24 - - - &Retweeter Home - - - 306, 24 - - - User defined URL - - - 347, 24 - - - &Open as ... - - - 118, 22 - - - Post(&N) - - - 118, 22 - - - &ID - - - 118, 22 - - - &Source - - - 347, 24 - - - &Filter by ... - - - 347, 24 - - - Manage &Lists - - - 344, 6 - - - 311, 24 - - - Make read(&B) - - - 311, 24 - - - Make not read(&U) - - - 347, 24 - - - Change Unread state ... - - - 347, 24 - - - Jump next to read tweet - - - 344, 6 - - - 347, 24 - - - Select &All - - - 347, 24 - - - &Delete your tweet/DM - - - 347, 24 - - - Refresh(&U) - - - 347, 24 - - - Fetch previous tweets(&I)... - - - 93, 23 - - - &Operation - - - 248, 24 - - - Create &New Tab... - - - 248, 24 - - - &Rename Tab... - - - 245, 6 - - - 248, 24 - - - &Protect Tab - - - 248, 24 - - - Manage Reading(&U) - - - 248, 24 - - - Enable Alert Popup(&Q) - - - 245, 6 - - - 248, 24 - - - Edit &Filtering rules... - - - 245, 6 - - - 248, 24 - - - &Clear posts in this tab - - - 245, 6 - - - 248, 24 - - - &Delete this tab - - - 47, 23 - - - &Tab - - - 218, 24 - - - Auto Select - - - 218, 24 - - - Undo - - - 218, 24 - - - 218, 24 - - - 218, 24 - - - 218, 24 - - - 218, 24 - - - 294, 24 - - - &Shorten URL - - - 334, 22 - - - &Separation of multibyte character string from URL - - - 334, 22 - - - Prevent interpreting text as SMS command - - - 334, 22 - - - &URL is automatically shortened - - - 334, 22 - - - &Convert IdeographicSpace to Space - - - 334, 22 - - - Input field is &Multiline - - - 334, 22 - - - Left focus in input box after posting - - - 331, 6 - - - 334, 22 - - - &Pick a media file - - - 331, 6 - - - 334, 22 - - - &Toggle Hashtag - - - 334, 22 - - - &Hashtag Manager - - - 211, 22 - - - Post Settings - - - 294, 24 - - - Fetch User List - - - 291, 6 - - - 294, 24 - - - &Follow - - - 294, 24 - - - U&nfollow - - - 294, 24 - - - S&how Friendship - - - 291, 6 - - - 294, 24 - - - Show your profile - - - 294, 24 - - - Open your profile page - - - 291, 6 - - - 294, 24 - - - Show Profile selected user - - - 294, 24 - - - Specified &User's updates - - - 291, 6 - - - 294, 24 - - - Retweets of this tweet(&C) - - - 294, 24 - - - Edit Lists - - - 95, 23 - - - &Command - - - 278, 24 - - - %AppName% &Help Site - - - 278, 24 - - - Shortcut keys - - - 275, 6 - - - 278, 24 - - - Check for Updates (&G) - - - 275, 6 - - - 278, 24 - - - Twitter API Status (web) - - - 278, 24 - - - Twitter API Usage - - - 275, 6 - - - 278, 24 - - - &About %AppName%... - - - 278, 24 - - - 54, 23 - - - &Help - - - 574, 27 - - - - - - - - - 189, 24 - - - Make Read (&B) - - - 189, 24 - - - Make Not Read - - - 258, 24 - - - Change unread state - - - 258, 24 - - - Select &All - - - 258, 24 - - - Jump Next to read post - - - 255, 6 - - - 255, 6 - - - 258, 24 - - - Add to &Lists - - - 245, 24 - - - Referred &URL - - - 122, 22 - - - ID - - - 245, 24 - - - Open &Retweeter Home - - - 122, 22 - - - Post (&N) - - - 245, 24 - - - User defined URL - - - 258, 24 - - - &Delete - - - 122, 22 - - - &Source - - - 258, 24 - - - Filter by ... - - - 258, 24 - - - &Update - - - 247, 24 - - - Settings (&O)... - - - 244, 6 - - - 247, 24 - - - &Save... - - - 244, 6 - - - 247, 24 - - - Enable Alert Popup (&Q) - - - 247, 24 - - - Enable Sounds - - - 247, 24 - - - Stick &List - - - 244, 6 - - - 247, 24 - - - E&xit - - - 248, 166 - - - - - - 258, 24 - - - Fetch previous tweets - - - 245, 24 - - - Open Repl&ied Status - - - 245, 24 - - - &Open Status - - - 258, 24 - - - @ &Reply - - - 258, 24 - - - @ Reply ALL - - - 258, 24 - - - Send D&M - - - 258, 24 - - - 258, 24 - - - 258, 24 - - - 255, 6 - - - 258, 24 - - - Mark &Favorite - - - 258, 24 - - - Fav+Retweet - - - 258, 24 - - - Fav+Retweet(Unofficial) - - - 258, 24 - - - Unmark Favorite - - - 255, 6 - - - 258, 24 - - - User &Profile - - - 258, 24 - - - Related Posts (&G) - - - 258, 24 - - - &User's updates - - - 245, 24 - - - Open &Home page - - - 245, 24 - - - Open Favorites (&G) - - - 258, 24 - - - Open as ... - - - 259, 556 - - - - - - + + 334, 22 + &Toggle Hashtag + 445, 24 + &Toggle Hashtag + Icon size + 334, 22 + &Convert IdeographicSpace to Space + 445, 24 + &Convert IdeographicSpace to Space + 122, 22 + ID + 334, 22 + &Pick a media file + 445, 24 + &Pick a media file + 218, 24 + 218, 24 + 347, 24 + Jump next to read tweet + 258, 24 + Jump Next to read post + RemainCharacterLength + 452, 0 + + 247, 24 + Stick &List + 347, 24 + Manage &Lists + 294, 24 + Edit Lists + 258, 24 + Add to &Lists + 570, 149 + + 242, 24 + Stick &List + Lock sort order + 278, 24 + %AppName% &Help Site + 95, 23 + &Command + 49, 23 + &Edit + 47, 23 + &File + 54, 23 + &Help + 93, 23 + &Operation + 320, 24 + Find Ne&xt + 320, 24 + Find &Previous + 320, 24 + &Find... + 47, 23 + &Tab + 574, 27 + + 245, 24 + Open Favorites (&G) + 245, 24 + Open &Home page + 245, 24 + Open &Retweeter Home + 334, 22 + Input field is &Multiline + 445, 24 + Input field is &Multiline + 247, 24 + Enable Alert Popup (&Q) + 247, 24 + &Enable Alert Popup (&Q) + 242, 24 + Enable Alert popup(&Q) + 248, 24 + Enable Alert Popup(&Q) + 306, 24 + Favorites(&G) + 306, 24 + &Home + 347, 24 + &Open as ... + 294, 24 + Open your profile page + 306, 24 + Reply to(&I) + 306, 24 + &Retweeter Home + 306, 24 + Status(&O) + Open URL(&L)... + 245, 24 + Referred &URL + 306, 24 + Referred &Urls + 306, 24 + User defined URL + 245, 24 + User defined URL + 294, 24 + Show your profile + 242, 24 + Enable Sounds + 247, 24 + Enable Sounds + 511, 0 + + 211, 22 + Post Settings + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACW @@ -1448,18 +346,207 @@ Av8B8QGnAfEC/wHPAv8B+wHPAfsQ/wHzB/8B5wf/AYEH/wEBB/8BAQf/AQEH/wEDCf8BgQL/Ac8BgQHP Av8BAQL/AYcBAQGHAv8BAQL/AQMBAQEDAv8BAQH/Af4BQwEAAUMC/wEDAf8B/gHhAQIB4QL/AacC/wHx AacB8QL/Ac8C/wH7Ac8B+wL/Cw== - - - - Icon size - - - Lock sort order - - - 574, 382 - - - - - \ No newline at end of file + + 334, 22 + Prevent interpreting text as SMS command + 445, 24 + Prevent interpreting text as SMS command + 570, 149 + + 247, 24 + &Protect Tab + 248, 24 + &Protect Tab + 320, 24 + Input search &Query + 347, 24 + 258, 24 + 189, 24 + Make Read (&B) + 311, 24 + Make read(&B) + 258, 24 + Fetch previous tweets + 347, 24 + Refresh(&U) + 347, 24 + Fetch previous tweets(&I)... + 258, 24 + &Update + 294, 24 + U&nfollow + 248, 24 + &Rename Tab... + 245, 24 + Open Repl&ied Status + 347, 24 + @R&eply All + 258, 24 + @ Reply ALL + 347, 24 + @&Reply + 258, 24 + @ &Reply + 258, 24 + 258, 24 + 294, 24 + Retweets of this tweet(&C) + 347, 24 + 347, 24 + 242, 24 + &Save to text file + 247, 24 + &Save... + 347, 24 + Select &All + 258, 24 + Select &All + 242, 24 + Settings(&O)... + 247, 24 + Settings (&O)... + 278, 24 + Shortcut keys + 258, 24 + User &Profile + 347, 24 + User &Profile + 258, 24 + Related Posts (&G) + 347, 24 + Related Posts (&G) + 258, 24 + &User's updates + 347, 24 + User's updates + Select a wav file. + 122, 22 + &Source + + + 574, 327 + 153 + + + + 570, 168 + 141 + + + + 570, 168 + + 410, 23 + 245, 24 + &Open Status + 574, 28 + + PostBodyInput + 452, 22 + + 242, 24 + Stop Refresh + PostComposeArea + 122, 22 + Post (&N) + 247, 24 + Rename Tab + PostsListArea + 570, 149 + + 294, 24 + &Shorten URL + 218, 24 + + 574, 327 + + + + 574, 382 + + + 258, 24 + Change unread state + 258, 24 + Open as ... + 258, 24 + Filter by ... + 291, 6 + 255, 6 + 244, 6 + 317, 6 + 331, 6 + 275, 6 + 244, 6 + 275, 6 + 244, 6 + 244, 6 + 244, 6 + 255, 6 + 244, 6 + 239, 6 + 317, 6 + 239, 6 + 239, 6 + 344, 6 + 344, 6 + 344, 6 + 245, 6 + 245, 6 + 291, 6 + 245, 6 + 245, 6 + 291, 6 + 442, 6 + 344, 6 + 255, 6 + 255, 6 + 291, 6 + 239, 6 + 331, 6 + 317, 6 + 275, 6 + 442, 6 + 244, 6 + 242, 24 + &Restart + PostDetailsArea + ThumbnailArea + 55, 170 + + 278, 24 + Twitter API Status (web) + 320, 24 + Undo remove tab + 347, 24 + Unfavorite(&V) + 248, 24 + Manage Reading(&U) + 311, 24 + Make not read(&U) + 189, 24 + Make Not Read + 294, 24 + Fetch User List + 247, 24 + Manage Reading (&U) + 334, 22 + &URL is automatically shortened + 445, 24 + &URL is automatically shortened + 218, 24 + Auto Select + 334, 22 + &Separation of multibyte character string from URL + 445, 24 + &Separation of multibyte character string from URL + 218, 24 + Undo + 294, 24 + Show Profile selected user + 294, 24 + Specified &User's updates + 218, 24 + 278, 24 + Check for Updates (&G) + diff --git a/OpenTween/Tween.resx b/OpenTween/Tween.resx index 2a28a2028..73a72e978 100644 --- a/OpenTween/Tween.resx +++ b/OpenTween/Tween.resx @@ -1,2081 +1,849 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 237, 17 - - - - None - - - - False - - - - 401, 23 - - - ToolStripStatusLabel1 - - - MiddleLeft - - - 70, 23 - - - Starting... - - - Starting... - - - 76, 23 - - - API ???/??? - - - API rest unknown ???/??? -(reset after ??? minutes) - - - 651, 17 - - - 257, 22 - - - URLからの全角文字列の切り離し - - - 257, 22 - - - SMSコマンドを回避する - - - 257, 22 - - - 自動的にURLを短縮する - - - False - - - 257, 22 - - - 全角スペースを半角スペースにする - - - Ctrl+Y - - - 257, 22 - - - 発言欄複数行入力(&M) - - - 257, 22 - - - フォーカスを発言欄へロックする - - - 254, 6 - - - Ctrl+Shift+P - - - 257, 22 - - - 投稿画像選択(&P) - - - 254, 6 - - - Ctrl+Shift+T - - - 257, 22 - - - ハッシュタグ自動付加 - - - Ctrl+T - - - 257, 22 - - - ハッシュタグ設定 - - - 258, 214 - - - ContextMenuPostMode - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 50, 26 - - - #[-] - - - 0, 0 - - - 612, 28 - - - 0 - - - StatusStrip1 - - - StatusStrip1 - - - System.Windows.Forms.StatusStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripContainer1.BottomToolStripPanel - - - 0 - - - ToolStripContainer1.BottomToolStripPanel - - - System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripContainer1 - - - 4 - - - Fill - - - 0, 0 - - - Horizontal - - - 発言一覧表示部 - - - Bottom - - - 330, 93 - - - 199, 22 - - - タブ作成(&N)... - - - 199, 22 - - - タブ名の変更(&R) - - - 196, 6 - - - 199, 22 - - - タブを保護する(&P) - - - 199, 22 - - - 未読管理(&U) - - - 199, 22 - - - 新着通知表示(&Q) - - - 121, 23 - - - 再生するwavファイルを指定してください - - - 196, 6 - - - 199, 22 - - - 振り分けルール編集(&F)... - - - 196, 6 - - - 199, 22 - - - このタブの発言をクリア(&C) - - - 196, 6 - - - 199, 22 - - - タブ削除(&D) - - - 200, 231 - - - ContextMenuTabProperty - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Fill - - - 217, 93 - - - 16, 16 - - - Disable - - - 0, 0 - - - 0, 0, 0, 0 - - - 608, 280 - - - 0 - - - ListTab - - - System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TimelinePanel - - - 0 - - - Fill - - - 0, 0 - - - 608, 280 - - - 0 - - - TimelinePanel - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer1.Panel1 - - - 0 - - - True - - - Fill - - - 0, 0 - - - 608, 280 - - - 1 - - - False - - - ImageSelector - - - OpenTween.MediaSelector, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - SplitContainer1.Panel1 - - - 1 - - - Fill - - - 0, 0 - - - 608, 280 - - - 2 - - - False - - - ProfilePanel - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer1.Panel1 - - - 2 - - - SplitContainer1.Panel1 - - - System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer1 - - - 0 - - - Fill - - - 0, 0 - - - Fill - - - 0, 0 - - - Horizontal - - - 発言詳細部 - - - Fill - - - 0, 0 - - - 511, 85 - - - 2 - - - tweetDetailsView - - - OpenTween.TweetDetailsView, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - SplitContainer2.Panel1 - - - 0 - - - SplitContainer2.Panel1 - - - System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer2 - - - 0 - - - 0 - - - 発言投稿部 - - - 3 - - - 本文入力欄 - - - Top - - - 0, 0 - - - 0, 0, 0, 0 - - - 417, 19 - - - 0 - - - StatusText - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel2 - - - 0 - - - Fill - - - Off - - - 464, 0 - - - 0, 0, 0, 0 - - - 47, 25 - - - 2 - - - Post - - - PostButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel2 - - - 1 - - - 残り文字数 - - - Fill - - - Off - - - 420, 0 - - - 41, 25 - - - 1 - - - 999 - - - MiddleCenter - - - lblLen - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel2 - - - 2 - - - Fill - - - 0, 0 - - - 1 - - - 511, 25 - - - 3 - - - TableLayoutPanel2 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer2.Panel2 - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="StatusText" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="PostButton" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="lblLen" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,47,Absolute,47" /><Rows Styles="Percent,100,Absolute,25" /></TableLayoutSettings> - - - SplitContainer2.Panel2 - - - System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer2 - - - 1 - - - 511, 114 - - - 87 - - - 2 - - - 1 - - - SplitContainer2 - - - System.Windows.Forms.SplitContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer3.Panel1 - - - 0 - - - SplitContainer3.Panel1 - - - System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer3 - - - 0 - - - サムネイル表示部 - - - Fill - - - 0, 0 - - - 4, 4, 4, 4 - - - 93, 114 - - - 0 - - - tweetThumbnail1 - - - OpenTween.TweetThumbnail, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - SplitContainer3.Panel2 - - - 0 - - - SplitContainer3.Panel2 - - - System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer3 - - - 1 - - - 608, 114 - - - 511 - - - 2 - - - SplitContainer3 - - - System.Windows.Forms.SplitContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer1.Panel2 - - - 0 - - - SplitContainer1.Panel2 - - - System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SplitContainer1 - - - 1 - - - 23 - - - 612, 404 - - - 284 - - - 2 - - - 0 - - - SplitContainer1 - - - OpenTween.OTSplitContainer, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - ToolStripContainer1.ContentPanel - - - 0 - - - 612, 404 - - - ToolStripContainer1.ContentPanel - - - System.Windows.Forms.ToolStripContentPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripContainer1 - - - 0 - - - Fill - - - ToolStripContainer1.LeftToolStripPanel - - - System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripContainer1 - - - 1 - - - 0, 0 - - - ToolStripContainer1.RightToolStripPanel - - - System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripContainer1 - - - 2 - - - 612, 456 - - - 0 - - - ToolStripContainer1 - - - 531, 17 - - - None - - - 190, 22 - - - 設定(&O) - - - 187, 6 - - - 190, 22 - - - ツイートURLを開く(&L)... - - - 187, 6 - - - 190, 22 - - - ファイル保存(&S) - - - 187, 6 - - - 190, 22 - - - 新着通知(&Q) - - - 190, 22 - - - サウンド再生(&P) - - - 190, 22 - - - 新着時リスト固定(&L) - - - 187, 6 - - - 190, 22 - - - All Refresh Stop - - - 187, 6 - - - 190, 22 - - - 再起動(&R) - - - 190, 22 - - - 終了(&X) - - - 70, 20 - - - ファイル(&F) - - - 247, 22 - - - タブ削除の取消 - - - 244, 6 - - - 247, 22 - - - コピー(STOT形式テキスト)(&C) - - - 247, 22 - - - コピー(ステータスURL)(&S) - - - 247, 22 - - - コピー(ユーザーID)(&A) - - - 244, 6 - - - Ctrl+F - - - 247, 22 - - - 検索(&F)... - - - F3 - - - 247, 22 - - - 次を検索(&X) - - - Shift+F3 - - - 247, 22 - - - 前を検索(&P) - - - 244, 6 - - - Ctrl+Shift+F - - - 247, 22 - - - 抽出条件入力(&Q) - - - 60, 20 - - - 編集(&E) - - - Ctrl+R - - - 313, 22 - - - @返信(&R) - - - Ctrl+Shift+R - - - 313, 22 - - - @返信ALL(&E) - - - Ctrl+M - - - 313, 22 - - - DM送信(&M) - - - Alt+R - - - 313, 22 - - - Re&tweet - - - Alt+Shift+R - - - 313, 22 - - - Retweet(U&nofficial) - - - Ctrl+Q - - - 313, 22 - - - &Quote - - - 310, 6 - - - Ctrl+S - - - 313, 22 - - - Fav追加(&F) - - - 313, 22 - - - Fav追加+Retweet - - - 313, 22 - - - Fav追加+Retweet(Unofficial) - - - Ctrl+Shift+S - - - 313, 22 - - - Fav削除(&V) - - - 310, 6 - - - - - - Alt+P - - - 313, 22 - - - プロフィール表示 - - - 313, 22 - - - 関連発言表示(&G) - - - Ctrl+U - - - 313, 22 - - - ユーザーのタイムラインを表示 - - - Ctrl+H - - - 289, 22 - - - ホームを開く(&H) - - - Ctrl+G - - - 289, 22 - - - Favを開く(&G) - - - Ctrl+O - - - 289, 22 - - - ステータスを開く(&O) - - - Ctrl+I - - - 289, 22 - - - 返信元ステータスを開く(&I) - - - Ctrl+E - - - 289, 22 - - - 発言内URLを開く(&U) - - - Ctrl+Shift+H - - - 289, 22 - - - RTした人のホームを開く(&R) - - - 289, 22 - - - ユーザー定義のURL - - - 313, 22 - - - 開く(&O) - - - 210, 22 - - - タブ振り分けルール作成(&N) - - - 210, 22 - - - ID振り分けルール作成(&I) - - - 210, 22 - - - &Source振り分けルール作成 - - - 313, 22 - - - 振り分けルール作成(&C) - - - 313, 22 - - - リスト管理(&L) - - - 310, 6 - - - Ctrl+B - - - 228, 22 - - - 既読にする(&B) - - - Ctrl+Shift+B - - - 228, 22 - - - 未読にする(&U) - - - 313, 22 - - - 未読状態変更(&H) - - - 313, 22 - - - 未読へジャンプ(&J) - - - 310, 6 - - - Ctrl+A - - - 313, 22 - - - 全て選択(&A) - - - Ctrl+D - - - 313, 22 - - - 削除(&D) - - - F5 - - - 313, 22 - - - 更新(&U) - - - Shift+F5 - - - 313, 22 - - - 前データを取得(&I) - - - 62, 20 - - - 操作(&O) - - - 199, 22 - - - タブ作成(&N)... - - - 199, 22 - - - タブ名変更(&R) - - - 196, 6 - - - 199, 22 - - - タブを保護する(&P) - - - 199, 22 - - - 未読管理(&U) - - - 199, 22 - - - 新着通知表示(&Q) - - - 121, 23 - - - 196, 6 - - - 199, 22 - - - 振り分けルール編集(&F)... - - - 196, 6 - - - 199, 22 - - - このタブの発言をクリア(&C) - - - 196, 6 - - - Ctrl+W - - - 199, 22 - - - タブ削除(&D) - - - 54, 20 - - - タブ(&T) - - - Ctrl+L - - - 228, 22 - - - 短縮サービス自動選択 - - - False - - - 228, 22 - - - 元に戻す - - - 228, 22 - - - TinyURL - - - 228, 22 - - - is.gd - - - 228, 22 - - - bit.ly - - - 228, 22 - - - j.mp - - - 228, 22 - - - ux.nu - - - 257, 22 - - - 入力欄のURLを短縮変換 - - - 246, 22 - - - URLからの全角文字列の切り離し - - - 246, 22 - - - SMSコマンドを回避する - - - 246, 22 - - - 自動的にURLを短縮する - - - False - - - 246, 22 - - - 全角スペースを半角スペースにする - - - Ctrl+Y - - - 246, 22 - - - 発言欄複数行入力(&M) - - - 246, 22 - - - フォーカスを発言欄へロックする - - - 243, 6 - - - Ctrl+Shift+P - - - 246, 22 - - - 投稿画像選択(&P) - - - 243, 6 - - - Ctrl+Shift+T - - - 246, 22 - - - ハッシュタグ自動付加 - - - Ctrl+T - - - 246, 22 - - - ハッシュタグ設定 - - - 225, 22 - - - 投稿設定 - - - 257, 22 - - - 片思いユーザーリスト取得 - - - 254, 6 - - - 257, 22 - - - フォローする(&F) - - - 257, 22 - - - フォロー解除(&N) - - - 257, 22 - - - 相互フォロー状態表示(&H) - - - 254, 6 - - - 257, 22 - - - 自プロフィール表示 - - - 257, 22 - - - 自身のホームを開く - - - 254, 6 - - - 257, 22 - - - プロフィール表示 - - - 257, 22 - - - ユーザーのタイムラインを開く - - - 254, 6 - - - 257, 22 - - - この発言のRetweet回数を確認 - - - 257, 22 - - - リスト編集 - - - 92, 20 - - - その他機能(&C) - - - F1 - - - 251, 22 - - - %AppName% ウェブサイト(&H) - - - 251, 22 - - - ショートカットキー一覧 - - - 248, 6 - - - 251, 22 - - - 最新版の取得(&G) - - - 248, 6 - - - 251, 22 - - - Twitter API 稼働状況 - - - 251, 22 - - - Twitter API 使用情報 - - - 248, 6 - - - 251, 22 - - - %AppName% について(&A)... - - - 200, 22 - - - PostClassのダンプ - - - 200, 22 - - - TraceOut出力 - - - 200, 22 - - - アイコンキャッシュ使用状況 - - - 251, 22 - - - デバッグモード - - - False - - - 67, 20 - - - ヘルプ(&H) - - - 0, 0 - - - 612, 24 - - - 0 - - - MenuStrip1 - - - MenuStrip1 - - - System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripContainer1.TopToolStripPanel - - - 0 - - - ToolStripContainer1.TopToolStripPanel - - - System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripContainer1 - - - 3 - - - ToolStripContainer1 - - - System.Windows.Forms.ToolStripContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - 144, 22 - - - 既読にする(&B) - - - 144, 22 - - - 未読にする - - - 241, 22 - - - 未読状態変更(&H) - - - 241, 22 - - - 全て選択(&A) - - - 241, 22 - - - 未読へジャンプ(&J) - - - 238, 6 - - - 238, 6 - - - 241, 22 - - - リスト管理(&L) - - - 205, 22 - - - 発言内URLを開く(&U) - - - 222, 22 - - - ID振り分けルール作成... - - - 205, 22 - - - RTした人のホームを開く(&R) - - - 222, 22 - - - タブ振り分けルール作成(&N)... - - - 205, 22 - - - ユーザー定義のURL - - - 241, 22 - - - 削除(&D) - - - 222, 22 - - - &Source振り分けルール作成... - - - 241, 22 - - - 振り分けルール作成(&C) - - - 241, 22 - - - 更新(&U) - - - 395, 55 - - - 516, 55 - - - 175, 22 - - - 設定(&O)... - - - 172, 6 - - - 175, 22 - - - ファイル保存(&S)... - - - 172, 6 - - - 175, 22 - - - 新着通知(&Q) - - - 175, 22 - - - サウンド再生(&P) - - - 175, 22 - - - 新着時リスト固定(&L) - - - 172, 6 - - - False - - - 175, 22 - - - 終了(&X) - - - 176, 154 - - - ContextMenuFile - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Tween - - - 241, 22 - - - 前データを取得(&I) - - - 535, 93 - - - 681, 93 - - - 205, 22 - - - 返信元ステータスを開く(&I) - - - 205, 22 - - - ステータスを開く(&O) - - - 667, 55 - - - 241, 22 - - - @返信(&R) - - - 241, 22 - - - @返信ALL(&E) - - - 241, 22 - - - DM送信(&M) - - - 241, 22 - - - Re&tweet - - - 241, 22 - - - Retweet(U&nofficial) - - - 241, 22 - - - &Quote - - - 238, 6 - - - 241, 22 - - - Fav追加(&F) - - - 241, 22 - - - Fav追加+Retweet - - - 241, 22 - - - Fav追加+Retweet(Unofficial) - - - 241, 22 - - - Fav削除(&V) - - - 238, 6 - - - 241, 22 - - - プロフィール表示 - - - 241, 22 - - - 関連発言表示(&G) - - - 241, 22 - - - ユーザーのタイムラインを表示 - - - 205, 22 - - - ホームを開く(&H) - - - 205, 22 - - - Favを開く(&G) - - - 241, 22 - - - 開く(&O) - - - 242, 534 - - - ContextMenuOperate - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 176, 131 - - - 17, 131 - - - 363, 17 - - - + 96, 96 + 612, 456 + Off + True + Manual + Tween + 125 + TweenMain + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + AboutMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AddTabMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ApiUsageInfoMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + BitlyToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CacheInfoMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ChangeReadOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ClearTabMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ClearTbMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuColumnHeader + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuFile + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuOperate + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuPostMode + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuTabProperty + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CopySTOTMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CopyURLMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CopyUserIdStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CreateIdRuleOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CreateRuleOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CreateSourceRuleOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CreateTabRuleOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CreateTbMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DebugModeToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DeleteStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DeleteTabMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DeleteTbMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DelOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DmOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DMStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DumpPostClassToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + EditRuleTbMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + EndFileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + EndToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FavAddToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FavOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FavoriteRetweetContextMenu + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FavoriteRetweetMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FavoriteRetweetUnofficialContextMenu + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FavoriteRetweetUnofficialMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FavRemoveToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FilterEditMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FocusLockMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FocusLockPullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FollowCommandMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FriendshipMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + HashManageMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + HashManagePullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + HashStripSplitButton + System.Windows.Forms.ToolStripSplitButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + HashToggleMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + HashTogglePullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IconSize16ToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IconSize24ToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IconSize48_2ToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IconSize48ToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IconSizeNoneToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IconSizeToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IdeographicSpaceToSpaceMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IdeographicSpaceToSpacePullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IDRuleMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ImageSelectMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ImageSelector + SplitContainer1.Panel1 + OpenTween.MediaSelector, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 1 + ImageSelectPullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IsgdToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + JmpStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + JumpReadOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + JumpUnreadMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + lblLen + TableLayoutPanel2 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ListLockMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ListManageMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ListManageToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ListManageUserContextToolStripMenuItem2 + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ListTab + TimelinePanel + System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + LockListFileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + LockListSortOrderToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MatomeMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemCommand + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemEdit + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemFile + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemHelp + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemOperate + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemSearchNext + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemSearchPrev + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemSubSearch + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuItemTab + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MenuStrip1 + ToolStripContainer1.TopToolStripPanel + System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + MoveToFavToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MoveToHomeToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MoveToRTHomeMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MultiLineMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + MultiLinePullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + NewPostPopMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + NotifyDispMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + NotifyFileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + NotifyIcon1 + System.Windows.Forms.NotifyIcon, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + NotifyTbMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenFavOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenFileDialog1 + System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenHomeOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenOwnHomeMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenRepSourceOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenRterHomeMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenStatusOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenURLFileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenURLMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenUrlOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenUserSpecifiedUrlMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OpenUserSpecifiedUrlMenuItem2 + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + OwnStatusMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + PlaySoundFileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + PlaySoundMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + PostButton + TableLayoutPanel2 + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + PostModeMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + PostStateImageList + System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + PreventSmsCommandMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + PreventSmsCommandPullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ProfilePanel + SplitContainer1.Panel1 + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ProtectTabMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ProtectTbMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + PublicSearchQueryMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + QtOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + QuoteStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ReadedStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ReadOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RefreshMoreStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RefreshOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RefreshPrevOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RefreshStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RemoveCommandMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RenameTbMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RepliedStatusOpenMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ReplyAllOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ReplyAllStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ReplyOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ReplyStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ReTweetStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ReTweetUnofficialStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RtCountMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RtOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RtUnOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SaveFileDialog1 + System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SaveFileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SaveLogMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SelAllOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SelectAllMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SettingFileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SettingStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShortcutKeyListMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowProfileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowProfMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowRelatedStatusesMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowRelatedStatusesMenuItem2 + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowUserTimelineContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowUserTimelineToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SoundFileComboBox + System.Windows.Forms.ToolStripComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SoundFileTbComboBox + System.Windows.Forms.ToolStripComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SourceRuleMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SplitContainer1 + SplitContainer1.Panel1 + SplitContainer1 + System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + SplitContainer1.Panel2 + SplitContainer1 + System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + ToolStripContainer1.ContentPanel + OpenTween.OTSplitContainer, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 0 + SplitContainer2 + SplitContainer2.Panel1 + SplitContainer2 + System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + SplitContainer2.Panel2 + SplitContainer2 + System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + SplitContainer3.Panel1 + System.Windows.Forms.SplitContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + SplitContainer3 + SplitContainer3.Panel1 + SplitContainer3 + System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + SplitContainer3.Panel2 + SplitContainer3 + System.Windows.Forms.SplitterPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + SplitContainer1.Panel2 + System.Windows.Forms.SplitContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + StatusLabel + OpenTween.OpenTweenCustomControl.ToolStripLabelHistory, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + StatusLabelUrl + System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + StatusOpenMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + StatusStrip1 + ToolStripContainer1.BottomToolStripPanel + System.Windows.Forms.StatusStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + StatusText + TableLayoutPanel2 + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + StopRefreshAllMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TabImage + System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TableLayoutPanel2 + SplitContainer2.Panel2 + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TabMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TabRenameMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TimelinePanel + SplitContainer1.Panel1 + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TimerRefreshIcon + System.Windows.Forms.Timer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TinyUrlConvertToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TinyURLToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + toolStripApiGauge + OpenTween.ToolStripAPIGauge, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + ToolStripContainer1.BottomToolStripPanel + ToolStripContainer1 + System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + ToolStripContainer1.ContentPanel + ToolStripContainer1 + System.Windows.Forms.ToolStripContentPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + ToolStripContainer1.LeftToolStripPanel + ToolStripContainer1 + System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + ToolStripContainer1 + $this + ToolStripContainer1.RightToolStripPanel + ToolStripContainer1 + System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ToolStripContainer1.TopToolStripPanel + ToolStripContainer1 + System.Windows.Forms.ToolStripPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + System.Windows.Forms.ToolStripContainer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + ToolStripMenuItem11 + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripMenuItem6 + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripMenuItem7 + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator1 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator10 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator11 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator12 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + toolStripSeparator13 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator14 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator15 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator16 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator17 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator18 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator19 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator2 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator20 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator21 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator22 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator23 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator24 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator25 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator26 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator27 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator28 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator29 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator3 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator30 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator31 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator34 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator35 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator38 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator39 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator4 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator41 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator43 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + toolStripSeparator44 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator45 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + toolStripSeparator5 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator6 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator7 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator8 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator9 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolTip1 + System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TraceOutToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TweenRestartMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + tweetDetailsView + SplitContainer2.Panel1 + OpenTween.TweetDetailsView, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 0 + tweetThumbnail1 + SplitContainer3.Panel2 + OpenTween.TweetThumbnail, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 0 + TwitterApiStatusToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UndoRemoveTabMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UnFavOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UnreadMngTbMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UnreadOpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UnreadStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UpdateFollowersMenuItem1 + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UreadManageMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UrlAutoShortenMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UrlAutoShortenPullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UrlConvertAutoToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UrlMultibyteSplitMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UrlMultibyteSplitPullDownMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UrlUndoToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UserStatusToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UserTimelineToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UxnuMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + VerUpMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 251, 22 + %AppName% について(&A)... + 199, 22 + タブ作成(&N)... + 251, 22 + Twitter API 使用情報 + 228, 22 + bit.ly + 200, 22 + アイコンキャッシュ使用状況 + 313, 22 + 未読状態変更(&H) + 199, 22 + このタブの発言をクリア(&C) + 199, 22 + このタブの発言をクリア(&C) + 147, 54 + 17, 17 + 176, 154 + 516, 55 + 242, 534 + 667, 55 + 258, 214 + 651, 17 + 200, 231 + 330, 93 + 247, 22 + コピー(STOT形式テキスト)(&C) + 247, 22 + コピー(ステータスURL)(&S) + 247, 22 + コピー(ユーザーID)(&A) + 210, 22 + ID振り分けルール作成(&I) + 313, 22 + 振り分けルール作成(&C) + 210, 22 + &Source振り分けルール作成 + 210, 22 + タブ振り分けルール作成(&N) + 199, 22 + タブ作成(&N)... + 251, 22 + デバッグモード + False + 241, 22 + 削除(&D) + 199, 22 + タブ削除(&D) + Ctrl+W + 199, 22 + タブ削除(&D) + Ctrl+D + 313, 22 + 削除(&D) + Ctrl+M + 313, 22 + DM送信(&M) + 241, 22 + DM送信(&M) + 200, 22 + PostClassのダンプ + 199, 22 + 振り分けルール編集(&F)... + 190, 22 + 終了(&X) + False + 175, 22 + 終了(&X) + 241, 22 + Fav追加(&F) + Ctrl+S + 313, 22 + Fav追加(&F) + 241, 22 + Fav追加+Retweet + 313, 22 + Fav追加+Retweet + 241, 22 + Fav追加+Retweet(Unofficial) + 313, 22 + Fav追加+Retweet(Unofficial) + 241, 22 + Fav削除(&V) + 199, 22 + 振り分けルール編集(&F)... + 246, 22 + フォーカスを発言欄へロックする + 257, 22 + フォーカスを発言欄へロックする + 257, 22 + フォローする(&F) + 257, 22 + 相互フォロー状態表示(&H) + Ctrl+T + 246, 22 + ハッシュタグ設定 + Ctrl+T + 257, 22 + ハッシュタグ設定 + 50, 26 + #[-] + Ctrl+Shift+T + 246, 22 + ハッシュタグ自動付加 + Ctrl+Shift+T + 257, 22 + ハッシュタグ自動付加 + 170, 22 + 16*16 + 170, 22 + 24*24 + 170, 22 + 48*48(2Column) + 170, 22 + 48*48 + 170, 22 + none + 146, 22 + アイコンサイズ + 246, 22 + 全角スペースを半角スペースにする + 257, 22 + 全角スペースを半角スペースにする + 222, 22 + ID振り分けルール作成... + Ctrl+Shift+P + 246, 22 + 投稿画像選択(&P) + True + Fill + 0, 0 + 608, 280 + 1 + False + Ctrl+Shift+P + 257, 22 + 投稿画像選択(&P) + 228, 22 + is.gd + 228, 22 + j.mp + 313, 22 + 未読へジャンプ(&J) + 241, 22 + 未読へジャンプ(&J) + 残り文字数 + Fill + Off + 420, 0 + 41, 25 + 1 + 999 + MiddleCenter + 175, 22 + 新着時リスト固定(&L) + 313, 22 + リスト管理(&L) + 257, 22 + リスト編集 + 241, 22 + リスト管理(&L) + Bottom + Fill + Disable + 0, 0 + 0, 0, 0, 0 + 608, 280 + 0 + 190, 22 + 新着時リスト固定(&L) + 146, 22 + ソート順をロック + F1 + 251, 22 + %AppName% ウェブサイト(&H) + 92, 20 + その他機能(&C) + 60, 20 + 編集(&E) + 70, 20 + ファイル(&F) + 67, 20 + ヘルプ(&H) + 62, 20 + 操作(&O) + F3 + 247, 22 + 次を検索(&X) + Shift+F3 + 247, 22 + 前を検索(&P) + Ctrl+F + 247, 22 + 検索(&F)... + 54, 20 + タブ(&T) + None + 0, 0 + 612, 24 + 0 + MenuStrip1 + 531, 17 + 205, 22 + Favを開く(&G) + 205, 22 + ホームを開く(&H) + 205, 22 + RTした人のホームを開く(&R) + Ctrl+Y + 246, 22 + 発言欄複数行入力(&M) + Ctrl+Y + 257, 22 + 発言欄複数行入力(&M) + 175, 22 + 新着通知(&Q) + 199, 22 + 新着通知表示(&Q) + 190, 22 + 新着通知(&Q) + Tween + 395, 55 + 199, 22 + 新着通知表示(&Q) + Ctrl+G + 289, 22 + Favを開く(&G) + 681, 93 + Ctrl+H + 289, 22 + ホームを開く(&H) + 313, 22 + 開く(&O) + 257, 22 + 自身のホームを開く + Ctrl+I + 289, 22 + 返信元ステータスを開く(&I) + Ctrl+Shift+H + 289, 22 + RTした人のホームを開く(&R) + Ctrl+O + 289, 22 + ステータスを開く(&O) + 190, 22 + ツイートURLを開く(&L)... + 205, 22 + 発言内URLを開く(&U) + Ctrl+E + 289, 22 + 発言内URLを開く(&U) + 289, 22 + ユーザー定義のURL + 205, 22 + ユーザー定義のURL + 257, 22 + 自プロフィール表示 + 190, 22 + サウンド再生(&P) + 175, 22 + サウンド再生(&P) + Fill + Off + 464, 0 + 0, 0, 0, 0 + 47, 25 + 2 + Post + 225, 22 + 投稿設定 + AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACW @@ -2206,1404 +974,287 @@ Av8B8QGnAfEC/wHPAv8B+wHPAfsQ/wHzB/8B5wf/AYEH/wEBB/8BAQf/AQEH/wEDCf8BgQL/Ac8BgQHP Av8BAQL/AYcBAQGHAv8BAQL/AQMBAQEDAv8BAQH/Af4BQwEAAUMC/wEDAf8B/gHhAQIB4QL/AacC/wHx AacB8QL/Ac8C/wH7Ac8B+wL/Cw== - - - - 17, 17 - - - 170, 22 - - - none - - - 170, 22 - - - 16*16 - - - 170, 22 - - - 24*24 - - - 170, 22 - - - 48*48 - - - 170, 22 - - - 48*48(2Column) - - - 146, 22 - - - アイコンサイズ - - - 143, 6 - - - 146, 22 - - - ソート順をロック - - - 147, 54 - - - ContextMenuColumnHeader - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - True - - - 125 - - - 96, 96 - - - 612, 456 - - - Off - - - Manual - - - Tween - - - StatusLabelUrl - - - System.Windows.Forms.ToolStripStatusLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - StatusLabel - - - OpenTween.OpenTweenCustomControl.ToolStripLabelHistory, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - toolStripApiGauge - - - OpenTween.ToolStripAPIGauge, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - HashStripSplitButton - - - System.Windows.Forms.ToolStripSplitButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UrlMultibyteSplitPullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - PreventSmsCommandPullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UrlAutoShortenPullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IdeographicSpaceToSpacePullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MultiLinePullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FocusLockPullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator35 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ImageSelectPullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator8 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - HashTogglePullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - HashManagePullDownMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - AddTabMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TabRenameMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator20 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ProtectTabMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UreadManageMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - NotifyDispMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SoundFileComboBox - - - System.Windows.Forms.ToolStripComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator18 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FilterEditMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator19 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ClearTabMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator11 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DeleteTabMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TabImage - - - System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemFile - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SettingFileMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripSeparator44 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenURLFileMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator21 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SaveFileMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator23 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - NotifyFileMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - PlaySoundFileMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - LockListFileMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator43 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - StopRefreshAllMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator24 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TweenRestartMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EndFileMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemEdit - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UndoRemoveTabMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator12 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CopySTOTMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CopyURLMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CopyUserIdStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator6 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemSubSearch - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemSearchNext - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemSearchPrev - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator22 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - PublicSearchQueryMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemOperate - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReplyOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReplyAllOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DmOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RtOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RtUnOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - QtOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator25 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FavOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FavoriteRetweetMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FavoriteRetweetUnofficialMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UnFavOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator38 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowProfMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowRelatedStatusesMenuItem2 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowUserTimelineToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenHomeOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenFavOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenStatusOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenRepSourceOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenUrlOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenRterHomeMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenUserSpecifiedUrlMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CreateRuleOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CreateTabRuleOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CreateIdRuleOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CreateSourceRuleOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListManageMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator26 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ChangeReadOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReadOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UnreadOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - JumpReadOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator27 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SelAllOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DelOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RefreshOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RefreshPrevOpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemTab - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CreateTbMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RenameTbMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator28 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ProtectTbMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UnreadMngTbMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - NotifyTbMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SoundFileTbComboBox - - - System.Windows.Forms.ToolStripComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator29 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EditRuleTbMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator30 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ClearTbMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator31 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DeleteTbMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemCommand - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TinyUrlConvertToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UrlConvertAutoToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UrlUndoToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TinyURLToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IsgdToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - BitlyToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - JmpStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UxnuMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - PostModeMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UrlMultibyteSplitMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - PreventSmsCommandMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UrlAutoShortenMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IdeographicSpaceToSpaceMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MultiLineMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FocusLockMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripSeparator5 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ImageSelectMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - toolStripSeparator13 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - HashToggleMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - HashManageMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UpdateFollowersMenuItem1 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator1 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FollowCommandMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RemoveCommandMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FriendshipMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator3 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OwnStatusMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenOwnHomeMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator41 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserStatusToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserTimelineToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator34 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RtCountMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListManageToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MenuItemHelp - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MatomeMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShortcutKeyListMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator16 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - VerUpMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator14 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TwitterApiStatusToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ApiUsageInfoMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator7 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - AboutMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DebugModeToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DumpPostClassToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TraceOutToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CacheInfoMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReadedStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UnreadStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripMenuItem11 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SelectAllMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - JumpUnreadMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator4 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator10 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListManageUserContextToolStripMenuItem2 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenURLMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IDRuleMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MoveToRTHomeMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TabMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenUserSpecifiedUrlMenuItem2 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DeleteStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripMenuItem7 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SourceRuleMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RefreshStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - NotifyIcon1 - - - System.Windows.Forms.NotifyIcon, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SettingStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator9 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SaveLogMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator17 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - NewPostPopMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - PlaySoundMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListLockMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator15 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - EndToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RefreshMoreStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SaveFileDialog1 - - - System.Windows.Forms.SaveFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenFileDialog1 - - - System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RepliedStatusOpenMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - StatusOpenMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReplyStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReplyAllStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - DMStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReTweetStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReTweetUnofficialStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - QuoteStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator39 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FavAddToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FavoriteRetweetContextMenu - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FavoriteRetweetUnofficialContextMenu - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FavRemoveToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator2 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowProfileMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowRelatedStatusesMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowUserTimelineContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripMenuItem6 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MoveToHomeToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - MoveToFavToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolTip1 - - - System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TimerRefreshIcon - - - System.Windows.Forms.Timer, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - PostStateImageList - - - System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IconSizeToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IconSizeNoneToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IconSize16ToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IconSize24ToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IconSize48ToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IconSize48_2ToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator45 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - LockListSortOrderToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TweenMain - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + + 363, 17 + 246, 22 + SMSコマンドを回避する + 257, 22 + SMSコマンドを回避する + Fill + 0, 0 + 608, 280 + 2 + False + 199, 22 + タブを保護する(&P) + 199, 22 + タブを保護する(&P) + Ctrl+Shift+F + 247, 22 + 抽出条件入力(&Q) + Ctrl+Q + 313, 22 + &Quote + 241, 22 + &Quote + 144, 22 + 既読にする(&B) + Ctrl+B + 228, 22 + 既読にする(&B) + 241, 22 + 前データを取得(&I) + F5 + 313, 22 + 更新(&U) + Shift+F5 + 313, 22 + 前データを取得(&I) + 241, 22 + 更新(&U) + 257, 22 + フォロー解除(&N) + 199, 22 + タブ名変更(&R) + 205, 22 + 返信元ステータスを開く(&I) + Ctrl+Shift+R + 313, 22 + @返信ALL(&E) + 241, 22 + @返信ALL(&E) + Ctrl+R + 313, 22 + @返信(&R) + 241, 22 + @返信(&R) + 241, 22 + Re&tweet + 241, 22 + Retweet(U&nofficial) + 257, 22 + この発言のRetweet回数を確認 + Alt+R + 313, 22 + Re&tweet + Alt+Shift+R + 313, 22 + Retweet(U&nofficial) + 535, 93 + 190, 22 + ファイル保存(&S) + 175, 22 + ファイル保存(&S)... + Ctrl+A + 313, 22 + 全て選択(&A) + 241, 22 + 全て選択(&A) + 190, 22 + 設定(&O) + 175, 22 + 設定(&O)... + 251, 22 + ショートカットキー一覧 + 241, 22 + プロフィール表示 + + Alt+P + 313, 22 + プロフィール表示 + 241, 22 + 関連発言表示(&G) + 313, 22 + 関連発言表示(&G) + 241, 22 + ユーザーのタイムラインを表示 + Ctrl+U + 313, 22 + ユーザーのタイムラインを表示 + 121, 23 + 再生するwavファイルを指定してください + 121, 23 + 222, 22 + &Source振り分けルール作成... + Fill + 0, 0 + Horizontal + 23 + 612, 404 + 284 + 2 + 0 + Fill + 0, 0 + Horizontal + 0 + 511, 114 + 87 + 2 + 1 + Fill + 0, 0 + 608, 114 + 511 + 2 + 70, 23 + Starting... + Starting... + False + 401, 23 + ToolStripStatusLabel1 + MiddleLeft + 205, 22 + ステータスを開く(&O) + None + 0, 0 + 612, 28 + 0 + StatusStrip1 + 237, 17 + 本文入力欄 + Top + 0, 0 + 0, 0, 0, 0 + 417, 19 + 0 + 190, 22 + All Refresh Stop + 16, 16 + 217, 93 + 発言投稿部 + 3 + Fill + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="StatusText" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="PostButton" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="lblLen" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,Absolute,47,Absolute,47" /><Rows Styles="Percent,100,Absolute,25" /></TableLayoutSettings> + 0, 0 + 1 + 511, 25 + 3 + 222, 22 + タブ振り分けルール作成(&N)... + 199, 22 + タブ名の変更(&R) + 発言一覧表示部 + Fill + 0, 0 + 608, 280 + 0 + 17, 131 + 257, 22 + 入力欄のURLを短縮変換 + 228, 22 + TinyURL + 76, 23 + API ???/??? + API rest unknown ???/??? +(reset after ??? minutes) + 612, 404 + Fill + 0, 0 + 612, 456 + 0 + ToolStripContainer1 + 241, 22 + 未読状態変更(&H) + 241, 22 + 開く(&O) + 241, 22 + 振り分けルール作成(&C) + 254, 6 + 238, 6 + 196, 6 + 244, 6 + 243, 6 + 248, 6 + 172, 6 + 248, 6 + 172, 6 + 196, 6 + 196, 6 + 238, 6 + 196, 6 + 187, 6 + 244, 6 + 187, 6 + 187, 6 + 310, 6 + 310, 6 + 310, 6 + 196, 6 + 196, 6 + 254, 6 + 196, 6 + 196, 6 + 254, 6 + 254, 6 + 310, 6 + 238, 6 + 238, 6 + 254, 6 + 187, 6 + 187, 6 + 143, 6 + 243, 6 + 244, 6 + 248, 6 + 254, 6 + 172, 6 + 176, 131 + 200, 22 + TraceOut出力 + 190, 22 + 再起動(&R) + 発言詳細部 + Fill + 0, 0 + 2 + 511, 85 + サムネイル表示部 + Fill + 0, 0 + 4, 4, 4, 4 + 93, 114 + 0 + 251, 22 + Twitter API 稼働状況 + 247, 22 + タブ削除の取消 + Ctrl+Shift+S + 313, 22 + Fav削除(&V) + 199, 22 + 未読管理(&U) + Ctrl+Shift+B + 228, 22 + 未読にする(&U) + 144, 22 + 未読にする + 257, 22 + 片思いユーザーリスト取得 + 199, 22 + 未読管理(&U) + 246, 22 + 自動的にURLを短縮する + False + 257, 22 + 自動的にURLを短縮する + False + Ctrl+L + 228, 22 + 短縮サービス自動選択 + 246, 22 + URLからの全角文字列の切り離し + 257, 22 + URLからの全角文字列の切り離し + False + 228, 22 + 元に戻す + 257, 22 + プロフィール表示 + 257, 22 + ユーザーのタイムラインを開く + 228, 22 + ux.nu + 251, 22 + 最新版の取得(&G) + diff --git a/OpenTween/TweenAboutBox.en.resx b/OpenTween/TweenAboutBox.en.resx index 3da2581c6..06e9eb34c 100644 --- a/OpenTween/TweenAboutBox.en.resx +++ b/OpenTween/TweenAboutBox.en.resx @@ -1,125 +1,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - + About %AppName% + Company + Copyright + Product + Version + iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAA1o9JREFUeF7tXQWY FEcTzaEBIhA8EDwhHogQ/RPinhD3hDjEIUhwd4IHd3d3d3d3l2DB4+n+3+uZ2usdZuWOO3Tv+5pd7lZm @@ -1038,24 +929,6 @@ JNcZ8KsSJAQbkLSARiupAXdxOgMaNY2bDoGGzsX7XGL0fBwNnyE/n0/AL5zxs/QnVQyb+MPzE4sAkusq ib1u7Ay4Z8ALJnqjiGi7KEN1Rvq9fuzkx85A7AzEzkDsDMTOQOwMxM5A7AzEzkDsDMTOQOwMxM5A7AzE zkDsDMTOQOwMxM7A+XMG/g+vfKQUwgG5fQAAAABJRU5ErkJggg== - - - - Product - - - Version - - - Copyright - - - Company - - - &OK - - - About %AppName% - - \ No newline at end of file + + &OK + diff --git a/OpenTween/TweenAboutBox.resx b/OpenTween/TweenAboutBox.resx index 3fa352ebd..eba24cb25 100644 --- a/OpenTween/TweenAboutBox.resx +++ b/OpenTween/TweenAboutBox.resx @@ -1,435 +1,116 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Fill - - - - 3, 3 - - - - 2 - - - Fill - - - 136, 0 - - - 6, 0, 3, 0 - - - 257, 16 - - - 0 - - - 製品名 - - - MiddleLeft - - - LabelProductName - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel - - - 1 - - - Fill - - - 136, 29 - - - 6, 0, 3, 0 - - - 257, 16 - - - 0 - - - バージョン - - - MiddleLeft - - - LabelVersion - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel - - - 2 - - - Fill - - - 136, 58 - - - 6, 0, 3, 0 - - - 257, 16 - - - 0 - - - 著作権 - - - MiddleLeft - - - LabelCopyright - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel - - - 3 - - - Fill - - - 136, 87 - - - 6, 0, 3, 0 - - - 257, 16 - - - 0 - - - 会社名 - - - MiddleLeft - - - LabelCompanyName - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel - - - 4 - - - Fill - - - 136, 119 - - - 6, 3, 3, 3 - - - True - - - Both - - - 257, 53 - - - 0 - - - 説明: + 96, 96 + 414, 315 + True + 9, 8, 9, 8 + CenterParent + %AppName% のバージョン情報 + TweenAboutBox + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + ChangeLog + TableLayoutPanel + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + LabelCompanyName + TableLayoutPanel + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + LabelCopyright + TableLayoutPanel + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + LabelProductName + TableLayoutPanel + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + LabelVersion + TableLayoutPanel + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + LogoPictureBox + TableLayoutPanel + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + OKButton + TableLayoutPanel + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + TableLayoutPanel + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TextBoxDescription + TableLayoutPanel + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + Fill + 3, 178 + True + Both + 390, 83 + 1 + Fill + 136, 87 + 6, 0, 3, 0 + 257, 16 + 0 + 会社名 + MiddleLeft + Fill + 136, 58 + 6, 0, 3, 0 + 257, 16 + 0 + 著作権 + MiddleLeft + Fill + 136, 0 + 6, 0, 3, 0 + 257, 16 + 0 + 製品名 + MiddleLeft + Fill + 136, 29 + 6, 0, 3, 0 + 257, 16 + 0 + バージョン + MiddleLeft + Fill + 3, 3 + 124, 169 + Zoom + 0 + Bottom, Right + 318, 275 + 75, 21 + 0 + OK(&O) + 2 + Fill + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="LogoPictureBox" Row="0" RowSpan="5" Column="0" ColumnSpan="1" /><Control Name="LabelProductName" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="LabelVersion" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="LabelCopyright" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="LabelCompanyName" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="TextBoxDescription" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="OKButton" Row="6" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="ChangeLog" Row="5" RowSpan="1" Column="0" ColumnSpan="2" /></Controls><Columns Styles="Percent,33,Percent,67" /><Rows Styles="Percent,10,Percent,10,Percent,10,Percent,10,Percent,20,Percent,30,Percent,10" /></TableLayoutSettings> + 9, 8 + 7 + 396, 299 + 0 + Fill + 136, 119 + 6, 3, 3, 3 + True + Both + 257, 53 + 0 + 説明: (ランタイムに、ラベルのテキストはアプリケーションのアセンブリ情報に置き換えられます。 -プロジェクト デザイナの [アプリケーション] ペインで、アプリケーションのアセンブリ情報をカスタマイズします。) - - - TextBoxDescription - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel - - - 5 - - - Bottom, Right - - - 318, 275 - - - 75, 21 - - - 0 - - - OK(&O) - - - OKButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel - - - 6 - - - Fill - - - 3, 178 - - - True - - - Both - - - 390, 83 - - - 1 - - - ChangeLog - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel - - - 7 - - - Fill - - - 9, 8 - - - 7 - - - 396, 299 - - - 0 - - - TableLayoutPanel - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="LogoPictureBox" Row="0" RowSpan="5" Column="0" ColumnSpan="1" /><Control Name="LabelProductName" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="LabelVersion" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="LabelCopyright" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="LabelCompanyName" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="TextBoxDescription" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="OKButton" Row="6" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="ChangeLog" Row="5" RowSpan="1" Column="0" ColumnSpan="2" /></Controls><Columns Styles="Percent,33,Percent,67" /><Rows Styles="Percent,10,Percent,10,Percent,10,Percent,10,Percent,20,Percent,30,Percent,10" /></TableLayoutSettings> - - - 124, 169 - - - Zoom - - - 0 - - - LogoPictureBox - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel - - - 0 - - - True - - - 96, 96 - - - 414, 315 - - - 9, 8, 9, 8 - - - CenterParent - - - %AppName% のバージョン情報 - - - TweenAboutBox - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file +プロジェクト デザイナの [アプリケーション] ペインで、アプリケーションのアセンブリ情報をカスタマイズします。) + diff --git a/OpenTween/TweetDetailsView.en.resx b/OpenTween/TweetDetailsView.en.resx index 753d9ede9..a80c1a290 100644 --- a/OpenTween/TweetDetailsView.en.resx +++ b/OpenTween/TweetDetailsView.en.resx @@ -1,211 +1,38 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ProfileImage - - - - PostBody - - - &Search selecting words - - - &Copy - - - Copy &URL - - - Select &All - - - &Follow - - - &Unfollow - - - Friendship &Relation - - - &All User Friendship in this Tweet - - - User &Profile - - - User Timeline(&F) - - - Search &Mentions to this user - - - Filter by &Id ... - - - Add to &Lists - - - Use this &Hashtag - - - &Translate selecting words - - - Translate - - - &Follow - - - &Unfollow - - - Friendship &Relation - - - Add to &Lists - - - User &Profile - - - User &Timeline - - - Search &Mentions to this user - - - &Reload Icon - - - Save &Icon... - - - Current Tab(&Local) - - - Copy &Source - - - Copy Source &URL - - \ No newline at end of file + Current Tab(&Local) + &Follow + &Follow + &All User Friendship in this Tweet + Friendship &Relation + Filter by &Id ... + Add to &Lists + Add to &Lists + PostBody + &Reload Icon + &Unfollow + Save &Icon... + Search &Mentions to this user + Search &Mentions to this user + User &Timeline + User Timeline(&F) + Select &All + &Copy + &Search selecting words + &Translate selecting words + Friendship &Relation + User &Profile + User &Profile + Copy &Source + Copy Source &URL + Translate + &Unfollow + Copy &URL + Use this &Hashtag + ProfileImage + diff --git a/OpenTween/TweetDetailsView.resx b/OpenTween/TweetDetailsView.resx index ab42d9156..89f0daae2 100644 --- a/OpenTween/TweetDetailsView.resx +++ b/OpenTween/TweetDetailsView.resx @@ -1,843 +1,250 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - - - 4 - - - プロフィール画像 - - - 210, 17 - - - - 231, 22 - - - フォローする(&F) - - - 231, 22 - - - フォロー解除(&N) - - - 231, 22 - - - 相互フォロー状態表示(&H) - - - 231, 22 - - - リスト管理(&L) - - - 228, 6 - - - 231, 22 - - - プロフィール表示(&P) - - - 231, 22 - - - ユーザーのタイムラインを表示(&T) - - - 231, 22 - - - このユーザーへの@発言を検索(&S) - - - 228, 6 - - - 231, 22 - - - IconName - - - 231, 22 - - - 再読み込み(&R) - - - 231, 22 - - - 保存(&I)... - - - 232, 258 - - - ContextMenuUserPicture - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Off - - - - - - 3, 3 - - - 50, 50 - - - Zoom - - - 0 - - - UserPicture - - - OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - TableLayoutPanel1 - - - 0 - - - Fill - - - MS UI Gothic, 9pt, style=Bold - - - Off - - - 59, 3 - - - 3, 3, 3, 0 - - - 340, 14 - - - 1 - - - LblName - - - MiddleLeft - - - NameLabel - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 1 - - - 発言本文 - - - 17, 17 - - - 161, 22 - - - Google(&G) - - - 161, 22 - - - Wikipedia(&W) - - - 161, 22 - - - Twitter Search(&S) - - - 161, 22 - - - 現在のタブ(&L) - - - 231, 22 - - - 選択文字列で検索(&S) - - - 228, 6 - - - 231, 22 - - - 選択文字列をコピー(&C) - - - False - - - 231, 22 - - - URLをコピー(&U) - - - 231, 22 - - - すべて選択(&A) - - - 228, 6 - - - 231, 22 - - - フォローする(&F) - - - 231, 22 - - - フォロー解除(&N) - - - 231, 22 - - - 相互フォロー状態表示(&R) - - - 231, 22 - - - 全ユーザーのフォロー状態(&A) - - - 228, 6 - - - 231, 22 - - - プロフィール表示(&P) - - - 231, 22 - - - このユーザーのTLを取得(&F) - - - 231, 22 - - - このユーザーへの@発言を検索(&S) - - - 228, 6 - - - 231, 22 - - - ID振分ルール作成(&I) - - - 231, 22 - - - リスト管理(&L) - - - 228, 6 - - - 231, 22 - - - ハッシュタグを固定(&H) - - - 231, 22 - - - 選択した文字列を翻訳 - - - False - - - Alt+Shift+T - - - 231, 22 - - - この発言を翻訳 - - - 232, 386 - - - ContextMenuPostBrowser - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Fill - - - 59, 20 - - - 449, 62 - - - 4 - - - PostBrowser - - - System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 2 - - - Top, Bottom, Right - - - True - - - Off - - - 405, 3 - - - 3, 3, 3, 0 - - - 38, 14 - - - 1 - - - Label1 - - - MiddleRight - - - DateTimeLabel - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 3 - - - Top, Bottom, Left, Right - - - True - - - 398, 17 - - - 167, 22 - - - Sourceをコピー - - - 167, 22 - - - Source URLをコピー - - - 168, 48 - - - ContextMenuSource - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Off - - - 449, 3 - - - 3, 3, 3, 0 - - - 59, 14 - - - 7 - - - LinkLabel1 - - - MiddleRight - - - SourceLinkLabel - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TableLayoutPanel1 - - - 4 - - - Fill - - - 0, 0 - - - 2 - - - 511, 85 - - - 2 - - - TableLayoutPanel1 - - - System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="UserPicture" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="NameLabel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="PostBrowser" Row="1" RowSpan="1" Column="1" ColumnSpan="3" /><Control Name="DateTimeLabel" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="SourceLinkLabel" Row="0" RowSpan="1" Column="3" ColumnSpan="1" /></Controls><Columns Styles="Absolute,56,Percent,100,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0,Percent,100" /></TableLayoutSettings> - - - True - - - 96, 96 - - - 511, 85 - - - FollowToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UnFollowToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowFriendShipToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListManageUserContextToolStripMenuItem3 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator37 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowUserStatusToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SearchPostsDetailNameToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SearchAtPostsDetailNameToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripMenuItem1 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IconNameToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ReloadIconToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SaveIconPictureToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SelectionSearchContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SearchGoogleContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SearchWikipediaContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SearchPublicSearchContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - CurrentTabToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator13 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SelectionCopyContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UrlCopyContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SelectionAllContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator5 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FollowContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - RemoveContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FriendshipContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - FriendshipAllMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator36 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ShowUserStatusContextMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SearchPostsDetailToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SearchAtPostsDetailToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator32 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - IdFilterAddMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ListManageUserContextToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolStripSeparator33 - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UseHashtagMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SelectionTranslationToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TranslationToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SourceCopyMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SourceUrlCopyMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - TweetDetailsView - - - System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file + 96, 96 + True + 511, 85 + TweetDetailsView + System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuPostBrowser + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuSource + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuUserPicture + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + CurrentTabToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DateTimeLabel + TableLayoutPanel1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + FollowContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FollowToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FriendshipAllMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + FriendshipContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IconNameToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + IdFilterAddMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ListManageUserContextToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ListManageUserContextToolStripMenuItem3 + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + NameLabel + TableLayoutPanel1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + PostBrowser + TableLayoutPanel1 + System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + ReloadIconToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RemoveContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SaveIconPictureToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SearchAtPostsDetailNameToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SearchAtPostsDetailToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SearchGoogleContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SearchPostsDetailNameToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SearchPostsDetailToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SearchPublicSearchContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SearchWikipediaContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SelectionAllContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SelectionCopyContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SelectionSearchContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SelectionTranslationToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowFriendShipToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowUserStatusContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowUserStatusToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SourceCopyMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SourceLinkLabel + TableLayoutPanel1 + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + SourceUrlCopyMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TableLayoutPanel1 + $this + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + ToolStripMenuItem1 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator13 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator32 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator33 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator36 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator37 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ToolStripSeparator5 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TranslationToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UnFollowToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UrlCopyContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UseHashtagMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UserPicture + TableLayoutPanel1 + OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 0 + 232, 386 + 17, 17 + 168, 48 + 398, 17 + 232, 258 + 210, 17 + 161, 22 + 現在のタブ(&L) + Top, Bottom, Right + True + Off + 405, 3 + 3, 3, 3, 0 + 38, 14 + 1 + Label1 + MiddleRight + 231, 22 + フォローする(&F) + 231, 22 + フォローする(&F) + 231, 22 + 全ユーザーのフォロー状態(&A) + 231, 22 + 相互フォロー状態表示(&R) + 231, 22 + IconName + 231, 22 + ID振分ルール作成(&I) + 231, 22 + リスト管理(&L) + 231, 22 + リスト管理(&L) + Fill + MS UI Gothic, 9pt, style=Bold + Off + 59, 3 + 3, 3, 3, 0 + 340, 14 + 1 + LblName + MiddleLeft + 発言本文 + Fill + 59, 20 + 449, 62 + 4 + 231, 22 + 再読み込み(&R) + 231, 22 + フォロー解除(&N) + 231, 22 + 保存(&I)... + 231, 22 + このユーザーへの@発言を検索(&S) + 231, 22 + このユーザーへの@発言を検索(&S) + 161, 22 + Google(&G) + 231, 22 + ユーザーのタイムラインを表示(&T) + 231, 22 + このユーザーのTLを取得(&F) + 161, 22 + Twitter Search(&S) + 161, 22 + Wikipedia(&W) + 231, 22 + すべて選択(&A) + 231, 22 + 選択文字列をコピー(&C) + 231, 22 + 選択文字列で検索(&S) + 231, 22 + 選択した文字列を翻訳 + False + 231, 22 + 相互フォロー状態表示(&H) + 231, 22 + プロフィール表示(&P) + 231, 22 + プロフィール表示(&P) + 167, 22 + Sourceをコピー + Top, Bottom, Left, Right + True + Off + 449, 3 + 3, 3, 3, 0 + 59, 14 + 7 + LinkLabel1 + MiddleRight + 167, 22 + Source URLをコピー + + 4 + Fill + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="UserPicture" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="NameLabel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="PostBrowser" Row="1" RowSpan="1" Column="1" ColumnSpan="3" /><Control Name="DateTimeLabel" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="SourceLinkLabel" Row="0" RowSpan="1" Column="3" ColumnSpan="1" /></Controls><Columns Styles="Absolute,56,Percent,100,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0,Percent,100" /></TableLayoutSettings> + 0, 0 + 2 + 511, 85 + 2 + 228, 6 + 228, 6 + 228, 6 + 228, 6 + 228, 6 + 228, 6 + 228, 6 + Alt+Shift+T + 231, 22 + この発言を翻訳 + 231, 22 + フォロー解除(&N) + False + 231, 22 + URLをコピー(&U) + 231, 22 + ハッシュタグを固定(&H) + プロフィール画像 + Off + + 3, 3 + 50, 50 + Zoom + 0 + diff --git a/OpenTween/TweetThumbnail.en.resx b/OpenTween/TweetThumbnail.en.resx index fb5c2f2b6..33aefc088 100644 --- a/OpenTween/TweetThumbnail.en.resx +++ b/OpenTween/TweetThumbnail.en.resx @@ -1,163 +1,22 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - - - - - - 254, 22 - - - &Open - - - 254, 22 - - - &Copy URL - - - 251, 6 - - - 254, 22 - - - Search similar images (Google) - - - 254, 22 - - - Search similar images (SauceNAO) - - - 255, 98 - - - - - - - - \ No newline at end of file + + 255, 98 + + 254, 22 + &Copy URL + 254, 22 + &Open + + + 254, 22 + Search similar images (Google) + 254, 22 + Search similar images (SauceNAO) + 251, 6 + diff --git a/OpenTween/TweetThumbnail.resx b/OpenTween/TweetThumbnail.resx index de80de338..bbac2ffd1 100644 --- a/OpenTween/TweetThumbnail.resx +++ b/OpenTween/TweetThumbnail.resx @@ -1,276 +1,61 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - - - - - - 160, 150 - - - panelPictureBox - - - searchImageGoogleMenuItem - - - $this - - - 223, 22 - - - 220, 6 - - - 類似画像を検索 (SauceNAO) - - - toolStripSeparator1 - - - 223, 22 - - - TweetThumbnail - - - scrollBar - - - System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 類似画像を検索 (Google) - - - - - - 1 - - - contextMenuStrip - - - - 0 - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 143, 150 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - searchImageSauceNaoMenuItem - - - System.Windows.Forms.VScrollBar, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Fill - - - openMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 2 - - - 2, 2, 2, 2 - - - $this - - - System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - - - 1 - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 0, 0 - - - 開く(&O) - - - System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - copyUrlMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - URLをコピー(&C) - - - 224, 98 - - - 143, 0 - - - Right - - - 223, 22 - - - System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 223, 22 - - - 17, 150 - - - toolTip - - - True - - - 17, 17 - - - 110, 17 - - \ No newline at end of file + True + 160, 150 + + TweetThumbnail + System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + contextMenuStrip + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + copyUrlMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + openMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + panelPictureBox + $this + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + scrollBar + $this + System.Windows.Forms.VScrollBar, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + searchImageGoogleMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + searchImageSauceNaoMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + toolStripSeparator1 + System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + toolTip + System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 224, 98 + + 110, 17 + 223, 22 + URLをコピー(&C) + 223, 22 + 開く(&O) + Fill + 0, 0 + 2, 2, 2, 2 + 143, 150 + 1 + + Right + 143, 0 + 17, 150 + 0 + + 223, 22 + 類似画像を検索 (Google) + 223, 22 + 類似画像を検索 (SauceNAO) + 220, 6 + 17, 17 + diff --git a/OpenTween/UpdateDialog.en.resx b/OpenTween/UpdateDialog.en.resx index e63820d36..bf417fd94 100644 --- a/OpenTween/UpdateDialog.en.resx +++ b/OpenTween/UpdateDialog.en.resx @@ -1,132 +1,11 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - &Yes - - - Remind Me &Later - - - &Skip This Version - - - %AppName% Update Check - - \ No newline at end of file + %AppName% Update Check + Remind Me &Later + &Skip This Version + &Yes + diff --git a/OpenTween/UpdateDialog.resx b/OpenTween/UpdateDialog.resx index d91131bf6..1b4d24784 100644 --- a/OpenTween/UpdateDialog.resx +++ b/OpenTween/UpdateDialog.resx @@ -1,321 +1,76 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - Top, Bottom, Left, Right - - - - 13, 67 - - - 3, 3, 3, 8 - - - - True - - - Both - - - 535, 164 - - - 1 - - - Details - - - TextDetail - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - Top, Left, Right - - - 75, 13 - - - 473, 48 - - - 0 - - - Summary - - - MiddleLeft - - - LabelSummary - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - 13, 13 - - - 48, 48 - - - CenterImage - - - 1 - - - PictureBox1 - - - System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - Bottom, Right - - - 194, 242 - - - 80, 26 - - - 2 - - - はい (&Y) - - - ImageBeforeText - - - YesButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - Bottom, Right - - - 430, 242 - - - 118, 26 - - - 4 - - - 後で通知 (&L) - - - NoButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - Bottom, Right - - - NoControl - - - 280, 242 - - - 144, 26 - - - 3 - - - このバージョンを無視 (&S) - - - SkipButton - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - True - - - 96, 96 - - - 560, 280 - - - CenterScreen - - - %AppName%更新通知 - - - UpdateDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 560, 280 + True + CenterScreen + %AppName%更新通知 + UpdateDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + LabelSummary + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + NoButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + PictureBox1 + $this + System.Windows.Forms.PictureBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + SkipButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + TextDetail + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + YesButton + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + Top, Left, Right + 75, 13 + 473, 48 + 0 + Summary + MiddleLeft + Bottom, Right + 430, 242 + 118, 26 + 4 + 後で通知 (&L) + 13, 13 + 48, 48 + CenterImage + 1 + Bottom, Right + NoControl + 280, 242 + 144, 26 + 3 + このバージョンを無視 (&S) + Top, Bottom, Left, Right + 13, 67 + 3, 3, 3, 8 + True + Both + 535, 164 + 1 + Details + Bottom, Right + 194, 242 + 80, 26 + 2 + はい (&Y) + ImageBeforeText + diff --git a/OpenTween/UserInfoDialog.en.resx b/OpenTween/UserInfoDialog.en.resx index 952af691c..99a549914 100644 --- a/OpenTween/UserInfoDialog.en.resx +++ b/OpenTween/UserInfoDialog.en.resx @@ -1,361 +1,88 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Close - - - - - - - 34, 12 - - - Name - - - - - - 48, 12 - - - Location - - - - - - - - - 22, 12 - - - Bio - - - - - - - - - - - - - - - 53, 12 - - - Following - - - - - - 54, 12 - - - Followers - - - - - - - - - - - - Created at - - - - - - - - - 79, 12 - - - Tweets(Home) - - - - - - - - - 53, 12 - - - Favorites - - - - - - - - - Follow - - - - - - Unfollow - - - - - - - - - - - - - - - - - - - - - - - - 45, 12 - - - Verified - - - - - - 130, 22 - - - Copy - - - 130, 22 - - - Select All - - - - - - 64, 12 - - - Latest Post - - - - - - - - - Statuses - - - - - - - - - Account ID - - - - - - Edit - - - - - - - - - - - - - - - - - - - - - - - - Block - - - - - - Rpt Spam - - - - - - Unblock - - - - - - 54, 12 - - - Protected - - - - - - Profile - - - - - \ No newline at end of file + Profile + + Block + + Unblock + + Close + + Edit + + Follow + + Rpt Spam + + Statuses + + Unfollow + + + + + 34, 12 + Name + + Account ID + + 48, 12 + Location + + + 22, 12 + Bio + + 53, 12 + Following + + 54, 12 + Followers + + Created at + + 79, 12 + Tweets(Home) + + 53, 12 + Favorites + + + + + + + + + + 64, 12 + Latest Post + + + 45, 12 + Verified + + 54, 12 + Protected + + + + + + + + 130, 22 + Select All + 130, 22 + Copy + + + + + + diff --git a/OpenTween/UserInfoDialog.resx b/OpenTween/UserInfoDialog.resx index 69e7e36bd..a22ace712 100644 --- a/OpenTween/UserInfoDialog.resx +++ b/OpenTween/UserInfoDialog.resx @@ -1,1464 +1,457 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - True - - - - 152, 127 - - - 86, 12 - - - 11 - - - 非公開(Protect) - - - LinkLabel2 - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 2 - - - True - - - 335, 182 - - - 75, 25 - - - 20 - - - ブロック解除 - - - ButtonBlockDestroy - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 3 - - - True - - - 497, 182 - - - 75, 25 - - - 22 - - - スパム報告 - - - ButtonReportSpam - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 4 - - - 170, 22 - - - 選択文字列をコピー - - - True - - - 416, 182 - - - 75, 25 - - - 21 - - - ブロック - - - ButtonBlock - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 5 - - - False - - - 12, 182 - - - 16, 19 - - - 40 - - - False - - - TextBoxDescription - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 6 - - - False - - - 12, 153 - - - 16, 19 - - - 39 - - - False - - - TextBoxWeb - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 7 - - - True - - - - NoControl - - - 12, 429 - - - 75, 25 - - - 35 - - - 編集 - - - ButtonEdit - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 8 - - - Top, Right - - - NoControl - - - 446, 56 - - - 126, 17 - - - 4 - - - LabelId - - - MiddleRight - - - LabelId - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 9 - - - 120, 17 - - - 170, 22 - - - すべて選択 - - - 171, 48 - - - ContextMenuRecentPostBrowser - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - False - - - 34, 182 - - - 16, 19 - - - 38 - - - False - - - TextBoxLocation - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 10 - - - 17, 17 - - - False - - - 34, 153 - - - 16, 19 - - - 37 - - - False - - - TextBoxName - - - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 11 - - - Top, Right - - - NoControl - - - 446, 41 - - - 126, 15 - - - 3 - - - アカウントID - - - TopRight - - - Label12 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 12 - - - True - - - NoControl - - - 243, 182 - - - 75, 25 - - - 19 - - - TLを取得 - - - ButtonSearchPosts - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 13 - - - True - - - NoControl - - - 384, 127 - - - 100, 12 - - - 13 - - - 認証済み(Verified) - - - LinkLabel1 - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 14 - - - 82, 303 - - - 490, 65 - - - 26 - - - RecentPostBrowser - - - System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 15 - - - 143, 22 - - - アイコンの変更 - - - Top, Right - - - NoControl - - - 497, 126 - - - 75, 17 - - - 14 - - - LabelIsVerified - - - MiddleLeft - - - LabelIsVerified - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 16 - - - 82, 211 - - - 490, 73 - - - 24 - - - DescriptionBrowser - - - System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 17 - - - MS UI Gothic, 12pt - - - NoControl - - - 9, 20 - - - 431, 22 - - - 0 - - - ScreenName - - - MiddleLeft - - - LabelScreenName - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 18 - - - True - - - NoControl - - - 10, 305 - - - 63, 12 - - - 25 - - - 最近の発言 - - - LabelRecentPost - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 19 - - - True - - - NoControl - - - 497, 429 - - - 75, 25 - - - 36 - - - 閉じる - - - ButtonClose - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 20 - - - 534, 17 - - - 144, 26 - - - ContextMenuUserPicture - - - System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - NoControl - - - - - - 12, 59 - - - 73, 73 - - - StretchImage - - - 1 - - - UserPicture - - - OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - - $this - - - 21 - - - True - - - NoControl - - - 414, 407 - - - 72, 12 - - - 34 - - - LinkLabelFav - - - LinkLabelFav - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 22 - - - True - - - NoControl - - - 290, 407 - - - 56, 12 - - - 33 - - - お気に入り - - - Label9 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 23 - - - Top, Right - - - NoControl - - - 253, 126 - - - 75, 17 - - - 12 - - - LabelIsProtected - - - MiddleLeft - - - LabelIsProtected - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 24 - - - Top, Right - - - NoControl - - - 446, 24 - - - 126, 17 - - - 2 - - - LabelCreatedAt - - - MiddleRight - - - LabelCreatedAt - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 25 - - - True - - - NoControl - - - 107, 408 - - - 84, 12 - - - 32 - - - LinkLabelTweet - - - LinkLabelTweet - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 26 - - - True - - - NoControl - - - 364, 156 - - - 84, 12 - - - 16 - - - Getting datas ... - - - LabelIsFollowed - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 27 - - - True - - - NoControl - - - 14, 408 - - - 83, 12 - - - 31 - - - 発言数(ホーム) - - - Label8 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 28 - - - True - - - NoControl - - - 145, 156 - - - 84, 12 - - - 15 - - - Getting datas ... - - - LabelIsFollowing - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 29 - - - True - - - NoControl - - - 414, 383 - - - 102, 12 - - - 30 - - - LinkLabelFollowers - - - LinkLabelFollowers - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 30 - - - True - - - NoControl - - - 154, 182 - - - 76, 25 - - - 18 - - - フォロー解除 - - - ButtonUnFollow - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 31 - - - True - - - NoControl - - - 107, 383 - - - 101, 12 - - - 28 - - - LinkLabelFollowing - - - LinkLabelFollowing - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 32 - - - True - - - NoControl - - - 290, 383 - - - 87, 12 - - - 29 - - - フォローされている - - - Label6 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 33 - - - NoControl - - - 154, 56 - - - 286, 17 - - - 6 - - - LabelName - - - MiddleLeft - - - LabelName - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 34 - - - True - - - NoControl - - - 72, 182 - - - 75, 25 - - - 17 - - - フォローする - - - ButtonFollow - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 35 - - - True - - - NoControl - - - 14, 383 - - - 77, 12 - - - 27 - - - フォローしている - - - Label5 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 36 - - - Top, Right - - - NoControl - - - 446, 9 - - - 126, 15 - - - 1 - - - アカウント作成日時 - - - TopRight - - - Label7 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 37 - - - True - - - NoControl - - - 10, 215 - - - 53, 12 - - - 23 - - - 自己紹介 - - - Label4 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 38 - - - NoControl - - - 154, 80 - - - 418, 17 - - - 8 - - - LabelLocation - - - MiddleLeft - - - LabelLocation - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 39 - - - 367, 17 - - - NoControl - - - 154, 103 - - - 418, 17 - - - 10 - - - LinkLabelWeb - - - MiddleLeft - - - LinkLabelWeb - - - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 40 - - - True - - - NoControl - - - 100, 57 - - - 29, 12 - - - 5 - - - 名前 - - - Label1 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 41 - - - True - - - NoControl - - - 100, 104 - - - 26, 12 - - - 9 - - - Web - - - Label3 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 42 - - - True - - - NoControl - - - 100, 81 - - - 41, 12 - - - 7 - - - 現在地 - - - Label2 - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 43 - - - True - - - 45 - - - 96, 96 - - - 584, 466 - - - CenterParent - - - ユーザー情報 - - - SelectionCopyToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - SelectAllToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ToolTip1 - - - System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - ChangeIconToolStripMenuItem - - - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - OpenFileDialogIcon - - - System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - UserInfoDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 584, 466 + True + CenterParent + ユーザー情報 + 45 + UserInfoDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + ButtonBlock + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + ButtonBlockDestroy + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + ButtonClose + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 20 + ButtonEdit + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 8 + ButtonFollow + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 35 + ButtonReportSpam + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + ButtonSearchPosts + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 13 + ButtonUnFollow + $this + System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 31 + ChangeIconToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuRecentPostBrowser + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ContextMenuUserPicture + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + DescriptionBrowser + $this + System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 17 + Label1 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 41 + Label12 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 12 + Label2 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 43 + Label3 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 42 + Label4 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 38 + Label5 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 36 + Label6 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 33 + Label7 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 37 + Label8 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 28 + Label9 + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 23 + LabelCreatedAt + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 25 + LabelId + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 9 + LabelIsFollowed + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 27 + LabelIsFollowing + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 29 + LabelIsProtected + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 24 + LabelIsVerified + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 16 + LabelLocation + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 39 + LabelName + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 34 + LabelRecentPost + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 19 + LabelScreenName + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 18 + LinkLabel1 + $this + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 14 + LinkLabel2 + $this + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + LinkLabelFav + $this + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 22 + LinkLabelFollowers + $this + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 30 + LinkLabelFollowing + $this + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 32 + LinkLabelTweet + $this + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 26 + LinkLabelWeb + $this + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 40 + OpenFileDialogIcon + System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RecentPostBrowser + $this + System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 + SelectAllToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + SelectionCopyToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + TextBoxDescription + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + TextBoxLocation + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 10 + TextBoxName + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 11 + TextBoxWeb + $this + System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + ToolTip1 + System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + UserPicture + $this + OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + 21 + True + 416, 182 + 75, 25 + 21 + ブロック + True + 335, 182 + 75, 25 + 20 + ブロック解除 + True + NoControl + 497, 429 + 75, 25 + 36 + 閉じる + True + NoControl + 12, 429 + 75, 25 + 35 + 編集 + True + NoControl + 72, 182 + 75, 25 + 17 + フォローする + True + 497, 182 + 75, 25 + 22 + スパム報告 + True + NoControl + 243, 182 + 75, 25 + 19 + TLを取得 + True + NoControl + 154, 182 + 76, 25 + 18 + フォロー解除 + 143, 22 + アイコンの変更 + 171, 48 + 120, 17 + 144, 26 + 534, 17 + 82, 211 + 490, 73 + 24 + True + NoControl + 100, 57 + 29, 12 + 5 + 名前 + Top, Right + NoControl + 446, 41 + 126, 15 + 3 + アカウントID + TopRight + True + NoControl + 100, 81 + 41, 12 + 7 + 現在地 + True + NoControl + 100, 104 + 26, 12 + 9 + Web + True + NoControl + 10, 215 + 53, 12 + 23 + 自己紹介 + True + NoControl + 14, 383 + 77, 12 + 27 + フォローしている + True + NoControl + 290, 383 + 87, 12 + 29 + フォローされている + Top, Right + NoControl + 446, 9 + 126, 15 + 1 + アカウント作成日時 + TopRight + True + NoControl + 14, 408 + 83, 12 + 31 + 発言数(ホーム) + True + NoControl + 290, 407 + 56, 12 + 33 + お気に入り + Top, Right + NoControl + 446, 24 + 126, 17 + 2 + LabelCreatedAt + MiddleRight + Top, Right + NoControl + 446, 56 + 126, 17 + 4 + LabelId + MiddleRight + True + NoControl + 364, 156 + 84, 12 + 16 + Getting datas ... + True + NoControl + 145, 156 + 84, 12 + 15 + Getting datas ... + Top, Right + NoControl + 253, 126 + 75, 17 + 12 + LabelIsProtected + MiddleLeft + Top, Right + NoControl + 497, 126 + 75, 17 + 14 + LabelIsVerified + MiddleLeft + NoControl + 154, 80 + 418, 17 + 8 + LabelLocation + MiddleLeft + NoControl + 154, 56 + 286, 17 + 6 + LabelName + MiddleLeft + True + NoControl + 10, 305 + 63, 12 + 25 + 最近の発言 + MS UI Gothic, 12pt + NoControl + 9, 20 + 431, 22 + 0 + ScreenName + MiddleLeft + True + NoControl + 384, 127 + 100, 12 + 13 + 認証済み(Verified) + True + 152, 127 + 86, 12 + 11 + 非公開(Protect) + True + NoControl + 414, 407 + 72, 12 + 34 + LinkLabelFav + True + NoControl + 414, 383 + 102, 12 + 30 + LinkLabelFollowers + True + NoControl + 107, 383 + 101, 12 + 28 + LinkLabelFollowing + True + NoControl + 107, 408 + 84, 12 + 32 + LinkLabelTweet + NoControl + 154, 103 + 418, 17 + 10 + LinkLabelWeb + MiddleLeft + 367, 17 + 82, 303 + 490, 65 + 26 + 170, 22 + すべて選択 + 170, 22 + 選択文字列をコピー + False + 12, 182 + 16, 19 + 40 + False + False + 34, 182 + 16, 19 + 38 + False + False + 34, 153 + 16, 19 + 37 + False + False + 12, 153 + 16, 19 + 39 + False + 17, 17 + NoControl + + 12, 59 + 73, 73 + StretchImage + 1 + diff --git a/OpenTween/WaitingDialog.resx b/OpenTween/WaitingDialog.resx index 6746d0bea..7f7758c16 100644 --- a/OpenTween/WaitingDialog.resx +++ b/OpenTween/WaitingDialog.resx @@ -1,192 +1,33 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - 12, 9 - - - 266, 45 - - - - 0 - - - labelMessage - - - MiddleCenter - - - labelMessage - - - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 0 - - - 12, 57 - - - 266, 23 - - - 1 - - - progressBar - - - System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - $this - - - 1 - - - True - - - 96, 96 - - - 290, 92 - - - - CenterParent - - - Information - - - WaitingDialog - - - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null - - \ No newline at end of file + 96, 96 + 290, 92 + True + CenterParent + Information + WaitingDialog + OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + labelMessage + $this + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + progressBar + $this + System.Windows.Forms.ProgressBar, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + 12, 9 + 266, 45 + 0 + labelMessage + MiddleCenter + 12, 57 + 266, 23 + 1 + From 2cb1d539983af1f6dc2c1dcb029aefaf00789544 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 30 Jan 2022 07:54:12 +0900 Subject: [PATCH 045/402] =?UTF-8?q?=E9=80=9A=E7=9F=A5=E9=96=A2=E4=BF=82?= =?UTF-8?q?=E3=81=AE=E8=A8=AD=E5=AE=9A=E9=A0=85=E7=9B=AE=E3=82=92NotifyPan?= =?UTF-8?q?el=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit panel1 は Anchor に Right を指定しているコントロールが高 DPI 環境下で正しくスケーリングされない問題の回避に必要となる --- OpenTween/AppendSettingDialog.cs | 12 -- OpenTween/AppendSettingDialog.en.resx | 4 +- OpenTween/AppendSettingDialog.resx | 4 +- OpenTween/Resources/ChangeLog.txt | 1 + .../Setting/Panel/ActionPanel.Designer.cs | 19 --- OpenTween/Setting/Panel/ActionPanel.cs | 2 - OpenTween/Setting/Panel/ActionPanel.resx | 67 ++++------ .../Setting/Panel/NotifyPanel.Designer.cs | 91 ++++++++++++++ OpenTween/Setting/Panel/NotifyPanel.cs | 23 ++++ OpenTween/Setting/Panel/NotifyPanel.en.resx | 23 ++++ OpenTween/Setting/Panel/NotifyPanel.resx | 109 ++++++++++++++++ .../Setting/Panel/PreviewPanel.Designer.cs | 53 -------- OpenTween/Setting/Panel/PreviewPanel.cs | 19 --- OpenTween/Setting/Panel/PreviewPanel.resx | 117 +++++------------- OpenTween/Tween.cs | 2 + 15 files changed, 306 insertions(+), 240 deletions(-) diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index 3cd416d5b..3e013e69b 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -137,18 +137,6 @@ private void TreeViewSetting_AfterSelect(object sender, TreeViewEventArgs e) if (pnl == null) return; pnl.Enabled = true; pnl.Visible = true; - - if (pnl.Name == "PreviewPanel") - { - if (GrowlHelper.IsDllExists) - { - this.PreviewPanel.IsNotifyUseGrowlCheckBox.Enabled = true; - } - else - { - this.PreviewPanel.IsNotifyUseGrowlCheckBox.Enabled = false; - } - } } private void Setting_FormClosing(object sender, FormClosingEventArgs e) diff --git a/OpenTween/AppendSettingDialog.en.resx b/OpenTween/AppendSettingDialog.en.resx index c8ca1fa2b..48d963e71 100644 --- a/OpenTween/AppendSettingDialog.en.resx +++ b/OpenTween/AppendSettingDialog.en.resx @@ -55,8 +55,8 @@ DFR3ZWV0UHJ2Tm9kZQD/////CQQAAAD/////CQQAAAAAAAAABQgAAAAdU3lzdGVtLldpbmRvd3MuRm9y bXMuVHJlZU5vZGUJAAAABFRleHQLVG9vbFRpcFRleHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJbmRleAhJ bWFnZUtleRJTZWxlY3RlZEltYWdlSW5kZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50AQEBAAAB - AAEAAQgICAIAAAAGDQAAABJFdmVudCBOb3RpZmljYXRpb24JBAAAAAYPAAAACk5vdGlmeU5vZGUA//// - /wkEAAAA/////wkEAAAAAAAAAAs= + AAEAAQgICAIAAAAGDQAAAAxOb3RpZmljYXRpb24JBAAAAAYPAAAACk5vdGlmeU5vZGUA/////wkEAAAA + /////wkEAAAAAAAAAAs= AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w diff --git a/OpenTween/AppendSettingDialog.resx b/OpenTween/AppendSettingDialog.resx index df47cd5b0..e808ac116 100644 --- a/OpenTween/AppendSettingDialog.resx +++ b/OpenTween/AppendSettingDialog.resx @@ -273,8 +273,8 @@ AAYLAAAADFR3ZWV0UHJ2Tm9kZQD/////CQQAAAD/////CQQAAAAAAAAABQgAAAAdU3lzdGVtLldpbmRv d3MuRm9ybXMuVHJlZU5vZGUJAAAABFRleHQLVG9vbFRpcFRleHQETmFtZQlJc0NoZWNrZWQKSW1hZ2VJ bmRleAhJbWFnZUtleRJTZWxlY3RlZEltYWdlSW5kZXgQU2VsZWN0ZWRJbWFnZUtleQpDaGlsZENvdW50 - AQEBAAABAAEAAQgICAIAAAAGDQAAABLjgqTjg5njg7Pjg4jpgJrnn6UJBAAAAAYPAAAACk5vdGlmeU5v - ZGUA/////wkEAAAA/////wkEAAAAAAAAAAs= + AQEBAAABAAEAAQgICAIAAAAGDQAAAAbpgJrnn6UJBAAAAAYPAAAACk5vdGlmeU5vZGUA/////wkEAAAA + /////wkEAAAAAAAAAAs= AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index a212275f1..f6e6efcaf 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -5,6 +5,7 @@ * CHG: Instagramのサムネイルを表示するURLのパターンを追加 * CHG: YouTubeのサムネイルを表示するURLのパターンを追加 (thx @Hawklaver!) * CHG: UserStreams関係の機能を削除 + * CHG: 設定画面にある通知関係の項目の配置を移動 * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) diff --git a/OpenTween/Setting/Panel/ActionPanel.Designer.cs b/OpenTween/Setting/Panel/ActionPanel.Designer.cs index 8378f1a7a..84606f20b 100644 --- a/OpenTween/Setting/Panel/ActionPanel.Designer.cs +++ b/OpenTween/Setting/Panel/ActionPanel.Designer.cs @@ -44,9 +44,7 @@ private void InitializeComponent() this.Label57 = new System.Windows.Forms.Label(); this.CheckFavRestrict = new System.Windows.Forms.CheckBox(); this.Button3 = new System.Windows.Forms.Button(); - this.PlaySnd = new System.Windows.Forms.CheckBox(); this.chkReadOwnPost = new System.Windows.Forms.CheckBox(); - this.Label15 = new System.Windows.Forms.Label(); this.BrowserPathText = new System.Windows.Forms.TextBox(); this.UReadMng = new System.Windows.Forms.CheckBox(); this.Label44 = new System.Windows.Forms.Label(); @@ -166,25 +164,12 @@ private void InitializeComponent() this.Button3.UseVisualStyleBackColor = true; this.Button3.Click += new System.EventHandler(this.Button3_Click); // - // PlaySnd - // - resources.ApplyResources(this.PlaySnd, "PlaySnd"); - this.PlaySnd.Name = "PlaySnd"; - this.PlaySnd.UseVisualStyleBackColor = true; - // // chkReadOwnPost // resources.ApplyResources(this.chkReadOwnPost, "chkReadOwnPost"); this.chkReadOwnPost.Name = "chkReadOwnPost"; this.chkReadOwnPost.UseVisualStyleBackColor = true; // - // Label15 - // - resources.ApplyResources(this.Label15, "Label15"); - this.Label15.BackColor = System.Drawing.SystemColors.ActiveCaption; - this.Label15.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; - this.Label15.Name = "Label15"; - // // BrowserPathText // resources.ApplyResources(this.BrowserPathText, "BrowserPathText"); @@ -231,9 +216,7 @@ private void InitializeComponent() this.Controls.Add(this.Label57); this.Controls.Add(this.CheckFavRestrict); this.Controls.Add(this.Button3); - this.Controls.Add(this.PlaySnd); this.Controls.Add(this.chkReadOwnPost); - this.Controls.Add(this.Label15); this.Controls.Add(this.BrowserPathText); this.Controls.Add(this.UReadMng); this.Controls.Add(this.Label44); @@ -265,9 +248,7 @@ private void InitializeComponent() internal System.Windows.Forms.Label Label57; internal System.Windows.Forms.CheckBox CheckFavRestrict; internal System.Windows.Forms.Button Button3; - internal System.Windows.Forms.CheckBox PlaySnd; internal System.Windows.Forms.CheckBox chkReadOwnPost; - internal System.Windows.Forms.Label Label15; internal System.Windows.Forms.TextBox BrowserPathText; internal System.Windows.Forms.CheckBox UReadMng; internal System.Windows.Forms.Label Label44; diff --git a/OpenTween/Setting/Panel/ActionPanel.cs b/OpenTween/Setting/Panel/ActionPanel.cs index 677dee471..702f3fd67 100644 --- a/OpenTween/Setting/Panel/ActionPanel.cs +++ b/OpenTween/Setting/Panel/ActionPanel.cs @@ -45,7 +45,6 @@ public ActionPanel() public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal) { this.UReadMng.Checked = settingCommon.UnreadManage; - this.PlaySnd.Checked = settingCommon.PlaySound; this.BrowserPathText.Text = settingLocal.BrowserPath; this.CheckCloseToExit.Checked = settingCommon.CloseToExit; this.CheckMinimizeToTray.Checked = settingCommon.MinimizeToTray; @@ -75,7 +74,6 @@ public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal) public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal) { - settingCommon.PlaySound = this.PlaySnd.Checked; settingCommon.UnreadManage = this.UReadMng.Checked; settingLocal.BrowserPath = this.BrowserPathText.Text.Trim(); settingCommon.CloseToExit = this.CheckCloseToExit.Checked; diff --git a/OpenTween/Setting/Panel/ActionPanel.resx b/OpenTween/Setting/Panel/ActionPanel.resx index 49ffb8f99..4eba03931 100644 --- a/OpenTween/Setting/Panel/ActionPanel.resx +++ b/OpenTween/Setting/Panel/ActionPanel.resx @@ -11,11 +11,11 @@ True 20, 10, 20, 10 ActionPanel - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null BrowserPathText $this System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 11 + 9 Button3 $this System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -23,7 +23,7 @@ CheckCloseToExit $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 14 + 12 CheckFavRestrict $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -31,7 +31,7 @@ CheckMinimizeToTray $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 15 + 13 CheckOpenUserTimeline $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -39,11 +39,11 @@ CheckReadOldPosts $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 16 + 14 chkReadOwnPost $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 9 + 8 GroupBox3 $this System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -76,10 +76,6 @@ GroupBox3 System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 3 - Label15 - $this - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 10 Label38 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -87,7 +83,7 @@ Label44 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 13 + 11 Label57 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -96,10 +92,6 @@ $this System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 2 - PlaySnd - $this - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 8 TabMouseLockCheck $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -107,52 +99,52 @@ UReadMng $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 12 - 185, 140 + 10 + 185, 101 228, 19 24 NoControl - 419, 139 + 419, 100 75, 21 25 参照 True NoControl - 23, 96 + 23, 57 171, 16 21 ×ボタンを押したときに終了する True NoControl - 23, 165 + 23, 126 183, 16 26 Fav操作結果を厳密にチェックする True NoControl - 23, 118 + 23, 79 170, 16 22 最小化したときにアイコン化する True NoControl - 23, 204 + 23, 165 180, 16 28 ユーザーのホームURLをタブで開く True NoControl - 23, 74 + 23, 35 145, 16 20 新着時に未読をクリアする True NoControl - 23, 226 + 23, 187 143, 16 29 自分の発言を既読にする - 24, 296 + 24, 257 473, 43 33 ホットキー @@ -196,28 +188,21 @@ 42, 16 4 Win - True - NoControl - 23, 32 - 3, 0, 3, 5 - 361, 12 - 18 - タブのサウンドを設定した上で、「再生する」を選ぶとサウンドが再生されます。 True NoControl - 24, 251 + 24, 212 142, 12 30 発言をダブルクリック時の動作 True NoControl - 23, 143 + 23, 104 60, 12 23 ブラウザパス True NoControl - 23, 184 + 23, 145 3, 0, 3, 5 340, 12 27 @@ -230,24 +215,18 @@ ユーザーのHomeを開く ステータスをWebで開く なし - 263, 248 + 263, 209 232, 20 31 - True - NoControl - 23, 13 - 113, 16 - 17 - サウンドを再生する True NoControl - 23, 274 + 23, 235 164, 16 32 マウスでのタブ移動を禁止する True NoControl - 23, 52 + 23, 13 100, 16 19 未読管理を行う diff --git a/OpenTween/Setting/Panel/NotifyPanel.Designer.cs b/OpenTween/Setting/Panel/NotifyPanel.Designer.cs index d356c68ae..c00bfb846 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.Designer.cs +++ b/OpenTween/Setting/Panel/NotifyPanel.Designer.cs @@ -28,18 +28,109 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NotifyPanel)); + this.CheckBoxNotificationPopup = new System.Windows.Forms.CheckBox(); + this.CheckBoxEnableNotificationSound = new System.Windows.Forms.CheckBox(); + this.label3 = new System.Windows.Forms.Label(); + this.label1 = new System.Windows.Forms.Label(); + this.ComboBoxNameInPopup = new System.Windows.Forms.ComboBox(); + this.label2 = new System.Windows.Forms.Label(); + this.CheckBoxUseGrowlForNotification = new System.Windows.Forms.CheckBox(); + this.CheckBoxEnableBlinkOnReply = new System.Windows.Forms.CheckBox(); + this.toolTip = new System.Windows.Forms.ToolTip(this.components); + this.panel1 = new System.Windows.Forms.Panel(); + this.panel1.SuspendLayout(); this.SuspendLayout(); // + // CheckBoxNotificationPopup + // + resources.ApplyResources(this.CheckBoxNotificationPopup, "CheckBoxNotificationPopup"); + this.CheckBoxNotificationPopup.Name = "CheckBoxNotificationPopup"; + this.CheckBoxNotificationPopup.UseVisualStyleBackColor = true; + // + // CheckBoxEnableNotificationSound + // + resources.ApplyResources(this.CheckBoxEnableNotificationSound, "CheckBoxEnableNotificationSound"); + this.CheckBoxEnableNotificationSound.Name = "CheckBoxEnableNotificationSound"; + this.CheckBoxEnableNotificationSound.UseVisualStyleBackColor = true; + // + // label3 + // + resources.ApplyResources(this.label3, "label3"); + this.label3.BackColor = System.Drawing.SystemColors.ActiveCaption; + this.label3.ForeColor = System.Drawing.SystemColors.ActiveCaptionText; + this.label3.Name = "label3"; + // + // label1 + // + resources.ApplyResources(this.label1, "label1"); + this.label1.Name = "label1"; + // + // ComboBoxNameInPopup + // + resources.ApplyResources(this.ComboBoxNameInPopup, "ComboBoxNameInPopup"); + this.ComboBoxNameInPopup.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.ComboBoxNameInPopup.FormattingEnabled = true; + this.ComboBoxNameInPopup.Items.AddRange(new object[] { + resources.GetString("ComboBoxNameInPopup.Items"), + resources.GetString("ComboBoxNameInPopup.Items1"), + resources.GetString("ComboBoxNameInPopup.Items2")}); + this.ComboBoxNameInPopup.Name = "ComboBoxNameInPopup"; + // + // label2 + // + resources.ApplyResources(this.label2, "label2"); + this.label2.Name = "label2"; + this.toolTip.SetToolTip(this.label2, resources.GetString("label2.ToolTip")); + // + // CheckBoxUseGrowlForNotification + // + resources.ApplyResources(this.CheckBoxUseGrowlForNotification, "CheckBoxUseGrowlForNotification"); + this.CheckBoxUseGrowlForNotification.Name = "CheckBoxUseGrowlForNotification"; + this.CheckBoxUseGrowlForNotification.UseVisualStyleBackColor = true; + // + // CheckBoxEnableBlinkOnReply + // + resources.ApplyResources(this.CheckBoxEnableBlinkOnReply, "CheckBoxEnableBlinkOnReply"); + this.CheckBoxEnableBlinkOnReply.Name = "CheckBoxEnableBlinkOnReply"; + this.CheckBoxEnableBlinkOnReply.UseVisualStyleBackColor = true; + // + // panel1 + // + this.panel1.Controls.Add(this.CheckBoxNotificationPopup); + this.panel1.Controls.Add(this.CheckBoxEnableBlinkOnReply); + this.panel1.Controls.Add(this.label1); + this.panel1.Controls.Add(this.label3); + this.panel1.Controls.Add(this.ComboBoxNameInPopup); + this.panel1.Controls.Add(this.CheckBoxEnableNotificationSound); + this.panel1.Controls.Add(this.CheckBoxUseGrowlForNotification); + this.panel1.Controls.Add(this.label2); + resources.ApplyResources(this.panel1, "panel1"); + this.panel1.Name = "panel1"; + // // NotifyPanel // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; + this.Controls.Add(this.panel1); this.Name = "NotifyPanel"; + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); this.ResumeLayout(false); } #endregion + private System.Windows.Forms.CheckBox CheckBoxNotificationPopup; + private System.Windows.Forms.CheckBox CheckBoxEnableNotificationSound; + private System.Windows.Forms.ToolTip toolTip; + private System.Windows.Forms.Label label3; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.ComboBox ComboBoxNameInPopup; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox CheckBoxUseGrowlForNotification; + private System.Windows.Forms.CheckBox CheckBoxEnableBlinkOnReply; + private System.Windows.Forms.Panel panel1; } } diff --git a/OpenTween/Setting/Panel/NotifyPanel.cs b/OpenTween/Setting/Panel/NotifyPanel.cs index 7e3ac68c3..b64862268 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.cs +++ b/OpenTween/Setting/Panel/NotifyPanel.cs @@ -40,10 +40,33 @@ public NotifyPanel() public void LoadConfig(SettingCommon settingCommon) { + this.CheckBoxNotificationPopup.Checked = settingCommon.NewAllPop; + this.ComboBoxNameInPopup.SelectedIndex = settingCommon.NameBalloon switch + { + MyCommon.NameBalloonEnum.None => 0, + MyCommon.NameBalloonEnum.UserID => 1, + MyCommon.NameBalloonEnum.NickName => 2, + _ => 2, + }; + this.CheckBoxUseGrowlForNotification.Checked = settingCommon.IsUseNotifyGrowl; + this.CheckBoxUseGrowlForNotification.Enabled = GrowlHelper.IsDllExists; + this.CheckBoxEnableNotificationSound.Checked = settingCommon.PlaySound; + this.CheckBoxEnableBlinkOnReply.Checked = settingCommon.BlinkNewMentions; } public void SaveConfig(SettingCommon settingCommon) { + settingCommon.NewAllPop = this.CheckBoxNotificationPopup.Checked; + settingCommon.NameBalloon = this.ComboBoxNameInPopup.SelectedIndex switch + { + 0 => MyCommon.NameBalloonEnum.None, + 1 => MyCommon.NameBalloonEnum.UserID, + 2 => MyCommon.NameBalloonEnum.NickName, + _ => throw new IndexOutOfRangeException(), + }; + settingCommon.IsUseNotifyGrowl = this.CheckBoxUseGrowlForNotification.Checked; + settingCommon.PlaySound = this.CheckBoxEnableNotificationSound.Checked; + settingCommon.BlinkNewMentions = this.CheckBoxEnableBlinkOnReply.Checked; } } } diff --git a/OpenTween/Setting/Panel/NotifyPanel.en.resx b/OpenTween/Setting/Panel/NotifyPanel.en.resx index cabc33e77..9886f6827 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.en.resx +++ b/OpenTween/Setting/Panel/NotifyPanel.en.resx @@ -3,5 +3,28 @@ 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 269, 16 + Blink window when new reply or DM is received + 221, 16 + Enable notification sound for new post + 221, 16 + Enable popup notification for new post + 190, 16 + Use Growl for popup notification + None + User ID + Nickname + 167, 12 + Username format in notification + 229, 12 + * Require Growl Connector Libraries (DLLs) + Require to get DLLs below and to copy to the path same as Tween.exe. +Growl.Connector.DLL +Growl.CoreLibrary.DLL +These are contained in 'Growl_NET_Connector_SDK.zip'. +This file is released for developers in Growl for Windows web site. + 435, 12 + If you enable it and set the sound file for tabs, the notification sound will be played. diff --git a/OpenTween/Setting/Panel/NotifyPanel.resx b/OpenTween/Setting/Panel/NotifyPanel.resx index f035d0984..9fda9b2f6 100644 --- a/OpenTween/Setting/Panel/NotifyPanel.resx +++ b/OpenTween/Setting/Panel/NotifyPanel.resx @@ -3,10 +3,119 @@ 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 96, 96 True + 0, 0, 0, 0 NotifyPanel OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null + CheckBoxEnableBlinkOnReply + panel1 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 + CheckBoxEnableNotificationSound + panel1 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 5 + CheckBoxNotificationPopup + panel1 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + CheckBoxUseGrowlForNotification + panel1 + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 6 + ComboBoxNameInPopup + panel1 + System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 + label1 + panel1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 2 + label2 + panel1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 7 + label3 + panel1 + System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 3 + panel1 + $this + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 + toolTip + System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + True + NoControl + 20, 156 + 0, 6, 6, 6 + 254, 16 + 7 + リプライまたはDMの新着時にウインドウを点滅する + True + NoControl + 20, 102 + 0, 6, 6, 6 + 157, 16 + 5 + 新着時に通知音を再生する + True + 20, 20 + 0, 6, 6, 6 + 196, 16 + 0 + 新着時にポップアップ通知を表示する + True + NoControl + 40, 74 + 20, 6, 6, 6 + 170, 16 + 3 + ポップアップ通知にGrowlを使用 + Top, Right + なし + ユーザーID + ニックネーム + 299, 46 + 3, 3, 0, 3 + 200, 20 + 2 + True + NoControl + 40, 49 + 20, 7, 7, 7 + 184, 12 + 1 + 通知ポップアップに表示するユーザー名 + Top, Right + True + NoControl + 276, 75 + 3, 0, 0, 0 + 223, 12 + 4 + ※別途DLLが必要です(マウスオーバーで表示) + Growl for Windowsの開発者向けに公開されている、 +Growl_NET_Connector_SDK.zipに同梱の次のDLLが必要です +Growl.Connector.DLL +Growl.CoreLibrary.DLL + + True + NoControl + 40, 131 + 20, 7, 7, 7 + 339, 12 + 6 + この項目を有効にした上で、タブごとの通知音を設定すると再生されます + Fill + 0, 0 + 20, 20, 20, 20 + 519, 368 + 0 + 17, 17 diff --git a/OpenTween/Setting/Panel/PreviewPanel.Designer.cs b/OpenTween/Setting/Panel/PreviewPanel.Designer.cs index 28c4798c2..ca6e9f858 100644 --- a/OpenTween/Setting/Panel/PreviewPanel.Designer.cs +++ b/OpenTween/Setting/Panel/PreviewPanel.Designer.cs @@ -28,13 +28,9 @@ protected override void Dispose(bool disposing) ///
private void InitializeComponent() { - this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PreviewPanel)); - this.Label2 = new System.Windows.Forms.Label(); - this.IsNotifyUseGrowlCheckBox = new System.Windows.Forms.CheckBox(); this.ReplyIconStateCombo = new System.Windows.Forms.ComboBox(); this.Label72 = new System.Windows.Forms.Label(); - this.ChkNewMentionsBlink = new System.Windows.Forms.CheckBox(); this.chkTabIconDisp = new System.Windows.Forms.CheckBox(); this.CheckPreviewEnable = new System.Windows.Forms.CheckBox(); this.Label81 = new System.Windows.Forms.Label(); @@ -43,27 +39,12 @@ private void InitializeComponent() this.CheckAlwaysTop = new System.Windows.Forms.CheckBox(); this.CheckMonospace = new System.Windows.Forms.CheckBox(); this.CheckBalloonLimit = new System.Windows.Forms.CheckBox(); - this.Label10 = new System.Windows.Forms.Label(); this.ComboDispTitle = new System.Windows.Forms.ComboBox(); this.Label45 = new System.Windows.Forms.Label(); - this.cmbNameBalloon = new System.Windows.Forms.ComboBox(); this.CheckDispUsername = new System.Windows.Forms.CheckBox(); this.CheckStatusAreaAtBottom = new System.Windows.Forms.CheckBox(); - this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.SuspendLayout(); // - // Label2 - // - resources.ApplyResources(this.Label2, "Label2"); - this.Label2.Name = "Label2"; - this.toolTip.SetToolTip(this.Label2, resources.GetString("Label2.ToolTip")); - // - // IsNotifyUseGrowlCheckBox - // - resources.ApplyResources(this.IsNotifyUseGrowlCheckBox, "IsNotifyUseGrowlCheckBox"); - this.IsNotifyUseGrowlCheckBox.Name = "IsNotifyUseGrowlCheckBox"; - this.IsNotifyUseGrowlCheckBox.UseVisualStyleBackColor = true; - // // ReplyIconStateCombo // this.ReplyIconStateCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; @@ -80,12 +61,6 @@ private void InitializeComponent() resources.ApplyResources(this.Label72, "Label72"); this.Label72.Name = "Label72"; // - // ChkNewMentionsBlink - // - resources.ApplyResources(this.ChkNewMentionsBlink, "ChkNewMentionsBlink"); - this.ChkNewMentionsBlink.Name = "ChkNewMentionsBlink"; - this.ChkNewMentionsBlink.UseVisualStyleBackColor = true; - // // chkTabIconDisp // resources.ApplyResources(this.chkTabIconDisp, "chkTabIconDisp"); @@ -139,11 +114,6 @@ private void InitializeComponent() this.CheckBalloonLimit.Name = "CheckBalloonLimit"; this.CheckBalloonLimit.UseVisualStyleBackColor = true; // - // Label10 - // - resources.ApplyResources(this.Label10, "Label10"); - this.Label10.Name = "Label10"; - // // ComboDispTitle // this.ComboDispTitle.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; @@ -165,17 +135,6 @@ private void InitializeComponent() resources.ApplyResources(this.Label45, "Label45"); this.Label45.Name = "Label45"; // - // cmbNameBalloon - // - this.cmbNameBalloon.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.cmbNameBalloon.FormattingEnabled = true; - this.cmbNameBalloon.Items.AddRange(new object[] { - resources.GetString("cmbNameBalloon.Items"), - resources.GetString("cmbNameBalloon.Items1"), - resources.GetString("cmbNameBalloon.Items2")}); - resources.ApplyResources(this.cmbNameBalloon, "cmbNameBalloon"); - this.cmbNameBalloon.Name = "cmbNameBalloon"; - // // CheckDispUsername // resources.ApplyResources(this.CheckDispUsername, "CheckDispUsername"); @@ -192,11 +151,8 @@ private void InitializeComponent() // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.Controls.Add(this.Label2); - this.Controls.Add(this.IsNotifyUseGrowlCheckBox); this.Controls.Add(this.ReplyIconStateCombo); this.Controls.Add(this.Label72); - this.Controls.Add(this.ChkNewMentionsBlink); this.Controls.Add(this.chkTabIconDisp); this.Controls.Add(this.CheckPreviewEnable); this.Controls.Add(this.Label81); @@ -205,10 +161,8 @@ private void InitializeComponent() this.Controls.Add(this.CheckAlwaysTop); this.Controls.Add(this.CheckMonospace); this.Controls.Add(this.CheckBalloonLimit); - this.Controls.Add(this.Label10); this.Controls.Add(this.ComboDispTitle); this.Controls.Add(this.Label45); - this.Controls.Add(this.cmbNameBalloon); this.Controls.Add(this.CheckDispUsername); this.Controls.Add(this.CheckStatusAreaAtBottom); this.Name = "PreviewPanel"; @@ -218,12 +172,8 @@ private void InitializeComponent() } #endregion - - internal System.Windows.Forms.Label Label2; - internal System.Windows.Forms.CheckBox IsNotifyUseGrowlCheckBox; internal System.Windows.Forms.ComboBox ReplyIconStateCombo; internal System.Windows.Forms.Label Label72; - internal System.Windows.Forms.CheckBox ChkNewMentionsBlink; internal System.Windows.Forms.CheckBox chkTabIconDisp; internal System.Windows.Forms.CheckBox CheckPreviewEnable; internal System.Windows.Forms.Label Label81; @@ -232,12 +182,9 @@ private void InitializeComponent() internal System.Windows.Forms.CheckBox CheckAlwaysTop; internal System.Windows.Forms.CheckBox CheckMonospace; internal System.Windows.Forms.CheckBox CheckBalloonLimit; - internal System.Windows.Forms.Label Label10; internal System.Windows.Forms.ComboBox ComboDispTitle; internal System.Windows.Forms.Label Label45; - internal System.Windows.Forms.ComboBox cmbNameBalloon; internal System.Windows.Forms.CheckBox CheckDispUsername; internal System.Windows.Forms.CheckBox CheckStatusAreaAtBottom; - private System.Windows.Forms.ToolTip toolTip; } } diff --git a/OpenTween/Setting/Panel/PreviewPanel.cs b/OpenTween/Setting/Panel/PreviewPanel.cs index 56b1f2665..416ed97ef 100644 --- a/OpenTween/Setting/Panel/PreviewPanel.cs +++ b/OpenTween/Setting/Panel/PreviewPanel.cs @@ -44,13 +44,6 @@ public PreviewPanel() public void LoadConfig(SettingCommon settingCommon) { - this.cmbNameBalloon.SelectedIndex = settingCommon.NameBalloon switch - { - MyCommon.NameBalloonEnum.None => 0, - MyCommon.NameBalloonEnum.UserID => 1, - MyCommon.NameBalloonEnum.NickName => 2, - _ => 2, - }; this.CheckDispUsername.Checked = settingCommon.DispUsername; this.ComboDispTitle.SelectedIndex = settingCommon.DispLatestPost switch { @@ -84,20 +77,10 @@ public void LoadConfig(SettingCommon settingCommon) "en" => 2, _ => 0, }; - this.ChkNewMentionsBlink.Checked = settingCommon.BlinkNewMentions; - this.IsNotifyUseGrowlCheckBox.Checked = settingCommon.IsUseNotifyGrowl; - this.IsNotifyUseGrowlCheckBox.Enabled = GrowlHelper.IsDllExists; } public void SaveConfig(SettingCommon settingCommon) { - settingCommon.NameBalloon = this.cmbNameBalloon.SelectedIndex switch - { - 0 => MyCommon.NameBalloonEnum.None, - 1 => MyCommon.NameBalloonEnum.UserID, - 2 => MyCommon.NameBalloonEnum.NickName, - _ => throw new IndexOutOfRangeException(), - }; settingCommon.DispUsername = this.CheckDispUsername.Checked; settingCommon.DispLatestPost = this.ComboDispTitle.SelectedIndex switch { @@ -131,8 +114,6 @@ public void SaveConfig(SettingCommon settingCommon) 2 => "en", _ => "en", }; - settingCommon.BlinkNewMentions = this.ChkNewMentionsBlink.Checked; - settingCommon.IsUseNotifyGrowl = this.IsNotifyUseGrowlCheckBox.Checked; } } } diff --git a/OpenTween/Setting/Panel/PreviewPanel.resx b/OpenTween/Setting/Panel/PreviewPanel.resx index ea8ffeeb7..024ba9f54 100644 --- a/OpenTween/Setting/Panel/PreviewPanel.resx +++ b/OpenTween/Setting/Panel/PreviewPanel.resx @@ -3,147 +3,113 @@ 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + - 96, 96 True 20, 10, 20, 10 PreviewPanel - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null CheckAlwaysTop $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 10 + 7 CheckBalloonLimit $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 12 + 9 CheckDispUsername $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 17 + 12 CheckMonospace $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 11 + 8 CheckPreviewEnable $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 6 + 3 CheckStatusAreaAtBottom $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 18 - ChkNewMentionsBlink - $this - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 4 + 13 chkTabIconDisp $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 5 - cmbNameBalloon - $this - System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 16 + 2 ComboDispTitle $this System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 14 - IsNotifyUseGrowlCheckBox - $this - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 - Label10 - $this - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 13 + 10 Label13 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 9 - Label2 - $this - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 0 + 6 Label45 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 15 + 11 Label72 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 3 + 1 Label81 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 7 + 4 LanguageCombo $this System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 8 + 5 ReplyIconStateCombo $this System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 2 - toolTip - System.Windows.Forms.ToolTip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 True NoControl - 23, 275 + 23, 227 133, 16 32 常に最前面に表示する True NoControl - 23, 67 + 23, 47 249, 16 22 画面最小化・アイコン時のみバルーンを表示する True NoControl - 23, 42 + 23, 22 235, 16 21 タイトルバーとツールチップにユーザー名を表示 True NoControl - 23, 250 + 23, 202 343, 16 31 発言詳細を等幅フォントで表示(AA対応、フォント適用不具合あり) True NoControl - 23, 200 + 23, 155 243, 16 29 画像リンクがあった場合にサムネイルを表示する True NoControl - 23, 225 + 23, 177 257, 16 30 発言詳細部・入力欄を発言一覧の下に配置する - True - NoControl - 23, 175 - 256, 16 - 28 - Mentionsの新着があるときにウインドウを点滅する True NoControl - 23, 121 + 23, 101 161, 16 25 タブに未読アイコンを表示する - なし - ユーザーID - ニックネーム - 276, 13 - 136, 20 - 20 (なし) バージョン 最終発言 @@ -152,66 +118,43 @@ 未読数(@未読数) 全未読/全発言数 発言数/フォロー数/フォロワー数 - 276, 92 + 276, 72 197, 20 24 - True - NoControl - 23, 329 - 119, 16 - 36 - 通知にGrowlを使用 - True - NoControl - 23, 16 - 130, 12 - 19 - 新着バルーンのユーザー名 True NoControl - 23, 303 + 23, 255 53, 12 33 Language - True - NoControl - 236, 330 - 223, 12 - 37 - ※別途DLLが必要です(マウスオーバーで表示) - Growl for Windowsの開発者向けに公開されている、 -Growl_NET_Connector_SDK.zipに同梱の次のDLLが必要です -Growl.Connector.DLL -Growl.CoreLibrary.DLL True NoControl - 23, 95 + 23, 75 60, 12 23 タイトルバー True NoControl - 23, 149 + 23, 129 134, 12 26 未読Mentions通知アイコン True NoControl - 92, 303 + 92, 255 115, 12 34 Apply after restarting OS Default Japanese English - 276, 300 + 276, 252 136, 20 35 通知なし アイコン変更 アイコン変更&点滅 - 276, 146 + 276, 126 136, 20 27 - 17, 17 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index a53e55d0f..e33a1e17a 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -3570,6 +3570,8 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) imgazyobizinet.Enabled = SettingManager.Common.EnableImgAzyobuziNet; imgazyobizinet.DisabledInDM = SettingManager.Common.ImgAzyobuziNetDisabledInDM; + this.NewPostPopMenuItem.Checked = SettingManager.Common.NewAllPop; + this.NotifyFileMenuItem.Checked = SettingManager.Common.NewAllPop; this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound; this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound; _fntUnread = SettingManager.Local.FontUnread; From c5249f1bf798b98afa3d36bacee2fbef3ba5fd75 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 30 Jan 2022 17:00:27 +0900 Subject: [PATCH 046/402] =?UTF-8?q?Reply,=20DM=20=E3=82=BF=E3=83=96?= =?UTF-8?q?=E4=BB=A5=E5=A4=96=E3=81=AE=E6=96=B0=E7=9D=80=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E3=82=92=E3=83=87=E3=83=95=E3=82=A9=E3=83=AB?= =?UTF-8?q?=E3=83=88=E3=81=A7=E3=82=AA=E3=83=95=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/TabInformationTest.cs | 37 +++++++++++++++++++- OpenTween/Models/TabInformations.cs | 30 ++++++++++++++++ OpenTween/Models/TabModel.cs | 2 +- OpenTween/Resources/ChangeLog.txt | 2 ++ OpenTween/Tween.cs | 26 ++------------ 5 files changed, 71 insertions(+), 26 deletions(-) diff --git a/OpenTween.Tests/Models/TabInformationTest.cs b/OpenTween.Tests/Models/TabInformationTest.cs index 6b272a122..8d1259f2a 100644 --- a/OpenTween.Tests/Models/TabInformationTest.cs +++ b/OpenTween.Tests/Models/TabInformationTest.cs @@ -35,7 +35,7 @@ public class TabInformationTest public TabInformationTest() { - this.tabinfo = (TabInformations)Activator.CreateInstance(typeof(TabInformations), true); + this.tabinfo = this.CreateInstance(); // TabInformation.GetInstance() で取得できるようにする var field = typeof(TabInformations).GetField("_instance", @@ -49,6 +49,9 @@ public TabInformationTest() this.tabinfo.AddTab(new FavoritesTabModel("Favorites")); } + private TabInformations CreateInstance() + => (TabInformations)Activator.CreateInstance(typeof(TabInformations), true); + [Fact] public void AddTab_Test() { @@ -105,6 +108,33 @@ public void SelectTab_Test() public void SelectTab_NotExistTest() => Assert.Throws(() => this.tabinfo.SelectTab("INVALID")); + [Fact] + public void AddDefaultTabs_Test() + { + var tabinfo = this.CreateInstance(); + Assert.Equal(0, tabinfo.Tabs.Count); + + tabinfo.AddDefaultTabs(); + + Assert.Equal(4, tabinfo.Tabs.Count); + Assert.IsType(tabinfo.Tabs[0]); + Assert.IsType(tabinfo.Tabs[1]); + Assert.IsType(tabinfo.Tabs[2]); + Assert.IsType(tabinfo.Tabs[3]); + + var homeTab = tabinfo.HomeTab; + Assert.False(homeTab.Notify); + + var mentionsTab = tabinfo.MentionTab; + Assert.True(mentionsTab.Notify); + + var dmTab = tabinfo.DirectMessageTab; + Assert.True(dmTab.Notify); + + var favsTab = tabinfo.FavoriteTab; + Assert.False(favsTab.Notify); + } + [Fact] public void MakeTabName_Test() { @@ -483,14 +513,17 @@ public void SubmitUpdate_NotifyPriorityTest() { var homeTab = this.tabinfo.HomeTab; homeTab.UnreadManage = true; + homeTab.Notify = true; homeTab.SoundFile = "home.wav"; var replyTab = this.tabinfo.MentionTab; replyTab.UnreadManage = true; + replyTab.Notify = true; replyTab.SoundFile = "reply.wav"; var dmTab = this.tabinfo.DirectMessageTab; dmTab.UnreadManage = true; + dmTab.Notify = true; dmTab.SoundFile = "dm.wav"; // 通常ツイート @@ -518,10 +551,12 @@ public void SubmitUpdate_IgnoreEmptySoundPath_Test() { var homeTab = this.tabinfo.HomeTab; homeTab.UnreadManage = true; + homeTab.Notify = true; homeTab.SoundFile = "home.wav"; var replyTab = this.tabinfo.MentionTab; replyTab.UnreadManage = true; + replyTab.Notify = true; replyTab.SoundFile = ""; // 通常ツイート diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index d3cce54ea..ca99569a3 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -208,6 +208,36 @@ public void SelectTab(string tabName) this.SelectedTabName = tabName; } + /// + /// デフォルトのタブを追加する + /// + public void AddDefaultTabs() + { + if (this.GetTabByType() == null) + this.AddTab(new HomeTabModel()); + + if (this.GetTabByType() == null) + { + var mentionsTab = new MentionsTabModel + { + Notify = true, + }; + this.AddTab(mentionsTab); + } + + if (this.GetTabByType() == null) + { + var dmTab = new DirectMessagesTabModel + { + Notify = true, + }; + this.AddTab(dmTab); + } + + if (this.GetTabByType() == null) + this.AddTab(new FavoritesTabModel()); + } + /// /// 指定されたタブ名を元に、既存のタブ名との重複を避けた名前を生成します /// diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index aa47d8b15..99a7d40aa 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -45,7 +45,7 @@ public abstract class TabModel public bool UnreadManage { get; set; } = true; public bool Protected { get; set; } - public bool Notify { get; set; } = true; + public bool Notify { get; set; } = false; public string SoundFile { get; set; } = ""; public ComparerMode SortMode { get; private set; } diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index f6e6efcaf..3f46b3e1f 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -6,6 +6,8 @@ * CHG: YouTubeのサムネイルを表示するURLのパターンを追加 (thx @Hawklaver!) * CHG: UserStreams関係の機能を削除 * CHG: 設定画面にある通知関係の項目の配置を移動 + * CHG: タブ別の新着通知表示のデフォルト設定を変更 + * Reply, DM タブ以外は新着通知表示がデフォルトでオフになります(従来はタブの種別に関わらずデフォルトでオン) * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index e33a1e17a..d18e33c71 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1120,23 +1120,6 @@ private void TweenMain_Load(object sender, EventArgs e) ApplyListViewIconSize(SettingManager.Common.IconSize); //<<<<<<<<タブ関連>>>>>>> - - //デフォルトタブの存在チェック、ない場合には追加 - if (this._statuses.GetTabByType() == null) - this._statuses.AddTab(new HomeTabModel()); - - if (this._statuses.GetTabByType() == null) - this._statuses.AddTab(new MentionsTabModel()); - - if (this._statuses.GetTabByType() == null) - this._statuses.AddTab(new DirectMessagesTabModel()); - - if (this._statuses.GetTabByType() == null) - this._statuses.AddTab(new FavoritesTabModel()); - - if (this._statuses.MuteTab == null) - this._statuses.AddTab(new MuteTabModel()); - foreach (var tab in _statuses.Tabs) { if (!AddNewTab(tab, startup: true)) @@ -1356,13 +1339,8 @@ private void LoadConfig() this._statuses.AddTab(tab); } - if (_statuses.Tabs.Count == 0) - { - _statuses.AddTab(new HomeTabModel()); - _statuses.AddTab(new MentionsTabModel()); - _statuses.AddTab(new DirectMessagesTabModel()); - _statuses.AddTab(new FavoritesTabModel()); - } + + this._statuses.AddDefaultTabs(); } private void TimerInterval_Changed(object sender, IntervalChangedEventArgs e) From 45d572d85f33ba1c1c79f6ca082048e9d914d906 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 30 Jan 2022 15:36:42 +0900 Subject: [PATCH 047/402] =?UTF-8?q?=E3=80=8CList=E3=81=AE=E7=99=BA?= =?UTF-8?q?=E8=A8=80=E5=8F=96=E5=BE=97=E3=81=AB=E5=85=AC=E5=BC=8FRT?= =?UTF-8?q?=E3=82=92=E5=90=AB=E3=82=81=E3=82=8B=E3=80=8D=E3=82=92=E3=83=87?= =?UTF-8?q?=E3=83=95=E3=82=A9=E3=83=AB=E3=83=88=E3=81=A7=E3=82=AA=E3=83=B3?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Setting/SettingCommon.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 3f46b3e1f..ec9a92d43 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -8,6 +8,7 @@ * CHG: 設定画面にある通知関係の項目の配置を移動 * CHG: タブ別の新着通知表示のデフォルト設定を変更 * Reply, DM タブ以外は新着通知表示がデフォルトでオフになります(従来はタブの種別に関わらずデフォルトでオン) + * CHG: 「Listの発言取得に公式RTを含める」のデフォルト設定をオンに変更 * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index ac8793169..38acc06ae 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -225,7 +225,10 @@ private string Decrypt(string password) public int MapThumbnailWidth = 200; public int MapThumbnailZoom = 15; public MapProvider MapThumbnailProvider = MapProvider.OpenStreetMap; - public bool IsListsIncludeRts = false; + + /// Listの発言取得に公式RTを含める + public bool IsListsIncludeRts = true; + public bool TabMouseLock = false; public bool IsUseNotifyGrowl = false; public bool ForceIPv4 = false; From 8feefc62284b598acd1533afe33ae5c4615af8cb Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 30 Jan 2022 22:19:32 +0900 Subject: [PATCH 048/402] =?UTF-8?q?POST=E3=82=AD=E3=83=BC=E3=81=AE?= =?UTF-8?q?=E3=83=87=E3=83=95=E3=82=A9=E3=83=AB=E3=83=88=E8=A8=AD=E5=AE=9A?= =?UTF-8?q?=E3=82=92=20Ctrl+Enter=20=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Setting/SettingCommon.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index ec9a92d43..daf62962a 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -9,6 +9,7 @@ * CHG: タブ別の新着通知表示のデフォルト設定を変更 * Reply, DM タブ以外は新着通知表示がデフォルトでオフになります(従来はタブの種別に関わらずデフォルトでオン) * CHG: 「Listの発言取得に公式RTを含める」のデフォルト設定をオンに変更 + * CHG: POSTキーのデフォルト設定を Ctrl+Enter に変更 * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index 38acc06ae..18114b648 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -134,7 +134,7 @@ private string Decrypt(string password) public bool OneWayLove = true; public MyCommon.NameBalloonEnum NameBalloon = MyCommon.NameBalloonEnum.NickName; - public bool PostCtrlEnter = false; + public bool PostCtrlEnter = true; public bool PostShiftEnter = false; public int CountApi = 60; public int CountApiReply = 40; From 96419a26e866b5f0a0048024c69b1088f39b3c0a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 1 Feb 2022 00:54:41 +0900 Subject: [PATCH 049/402] =?UTF-8?q?OpenUriInBrowserAsync=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=82=92MyCommon=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/MyCommonTest.cs | 45 ++++++++++++++++++ OpenTween/AppendSettingDialog.cs | 39 ++-------------- OpenTween/AuthDialog.cs | 12 +---- OpenTween/ListManage.cs | 5 +- OpenTween/MyCommon.cs | 62 +++++++++++++++++++++++++ OpenTween/SearchWordDialog.cs | 4 +- OpenTween/Tween.cs | 79 ++++++++------------------------ OpenTween/TweetDetailsView.cs | 10 ++-- OpenTween/UserInfoDialog.cs | 8 ++-- 9 files changed, 145 insertions(+), 119 deletions(-) diff --git a/OpenTween.Tests/MyCommonTest.cs b/OpenTween.Tests/MyCommonTest.cs index 84a394211..6c04b36af 100644 --- a/OpenTween.Tests/MyCommonTest.cs +++ b/OpenTween.Tests/MyCommonTest.cs @@ -305,5 +305,50 @@ public void CircularCountDown_StartFromLastIndexTest() Assert.Equal(new[] { 5, 4, 3, 2, 1, 0 }, actual); } + + [Fact] + public void CreateBrowserProcessStartInfo_DefaultBrowserTest() + { + var startInfo = MyCommon.CreateBrowserProcessStartInfo(browserPathWithArgs: null, "https://example.com/"); + Assert.Equal("https://example.com/", startInfo.FileName); + Assert.Equal("", startInfo.Arguments); + Assert.True(startInfo.UseShellExecute); + } + + [Fact] + public void CreateBrowserProcessStartInfo_BrowserPathTest() + { + var startInfo = MyCommon.CreateBrowserProcessStartInfo("C:\\browser.exe", "https://example.com/"); + Assert.Equal("C:\\browser.exe", startInfo.FileName); + Assert.Equal("\"https://example.com/\"", startInfo.Arguments); + Assert.False(startInfo.UseShellExecute); + } + + [Fact] + public void CreateBrowserProcessStartInfo_BrowserPathWithSpacesTest() + { + var startInfo = MyCommon.CreateBrowserProcessStartInfo("C:\\Program Files\\browser.exe", "https://example.com/"); + Assert.Equal("C:\\Program Files\\browser.exe", startInfo.FileName); + Assert.Equal("\"https://example.com/\"", startInfo.Arguments); + Assert.False(startInfo.UseShellExecute); + } + + [Fact] + public void CreateBrowserProcessStartInfo_QuotedBrowserPathTest() + { + var startInfo = MyCommon.CreateBrowserProcessStartInfo("\"C:\\Program Files\\browser.exe\"", "https://example.com/"); + Assert.Equal("C:\\Program Files\\browser.exe", startInfo.FileName); + Assert.Equal("\"https://example.com/\"", startInfo.Arguments); + Assert.False(startInfo.UseShellExecute); + } + + [Fact] + public void CreateBrowserProcessStartInfo_QuotedBrowserPathWithArgsTest() + { + var startInfo = MyCommon.CreateBrowserProcessStartInfo("\"C:\\Program Files\\browser.exe\" /hoge", "https://example.com/"); + Assert.Equal("C:\\Program Files\\browser.exe", startInfo.FileName); + Assert.Equal("/hoge \"https://example.com/\"", startInfo.Arguments); + Assert.False(startInfo.UseShellExecute); + } } } diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index 3e013e69b..ed774d177 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -301,43 +301,14 @@ private void Setting_Shown(object sender, EventArgs e) this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked; } - private void OpenUrl(string url) + private async Task OpenUrl(string url) { - var myPath = url; - var path = this.ActionPanel.BrowserPathText.Text; - try - { - if (!MyCommon.IsNullOrEmpty(path)) - { - if (path.StartsWith("\"", StringComparison.Ordinal) && path.Length > 2 && path.IndexOf("\"", 2, StringComparison.Ordinal) > -1) - { - var sep = path.IndexOf("\"", 2, StringComparison.Ordinal); - var browserPath = path.Substring(1, sep - 1); - var arg = ""; - if (sep < path.Length - 1) - { - arg = path.Substring(sep + 1); - } - myPath = arg + " " + myPath; - System.Diagnostics.Process.Start(browserPath, myPath); - } - else - { - System.Diagnostics.Process.Start(path, myPath); - } - } - else - { - System.Diagnostics.Process.Start(myPath); - } - } - catch(Exception) - { - } + var browserPathWithArgs = this.ActionPanel.BrowserPathText.Text; + await MyCommon.OpenInBrowserAsync(this, browserPathWithArgs, url); } - private void CreateAccountButton_Click(object sender, EventArgs e) - => this.OpenUrl("https://twitter.com/signup"); + private async void CreateAccountButton_Click(object sender, EventArgs e) + => await this.OpenUrl("https://twitter.com/signup"); private void GetPeriodPanel_IntervalChanged(object sender, IntervalChangedEventArgs e) => this.IntervalChanged?.Invoke(sender, e); diff --git a/OpenTween/AuthDialog.cs b/OpenTween/AuthDialog.cs index bdee1c75d..c861999fa 100644 --- a/OpenTween/AuthDialog.cs +++ b/OpenTween/AuthDialog.cs @@ -57,18 +57,10 @@ public string Pin set => PinTextBox.Text = value; } - private void AuthLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + private async void AuthLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { AuthLinkLabel.LinkVisited = true; - - try - { - System.Diagnostics.Process.Start(AuthUrl); - } - catch (Win32Exception ex) - { - MessageBox.Show(this, string.Format(Properties.Resources.BrowserStartFailed, ex.ErrorCode), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning); - } + await MyCommon.OpenInBrowserAsync(this, this.AuthUrl); } /// diff --git a/OpenTween/ListManage.cs b/OpenTween/ListManage.cs index 60b86be22..1e3b59ad8 100644 --- a/OpenTween/ListManage.cs +++ b/OpenTween/ListManage.cs @@ -410,10 +410,7 @@ private void UpdateListsListBox(IEnumerable lists) } private async void UserWeb_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - if (this.Owner != null) - await ((TweenMain)this.Owner).OpenUriInBrowserAsync(UserWeb.Text); - } + => await MyCommon.OpenInBrowserAsync(this, this.UserWeb.Text); private class NewListElement : ListElement { diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index bc06bd177..0629adf42 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -52,6 +52,8 @@ using OpenTween.Models; using OpenTween.Setting; using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using System.ComponentModel; namespace OpenTween { @@ -966,5 +968,65 @@ public static string UrlEncode(string stringToEncode) public static bool IsNullOrEmpty([NotNullWhen(false)] string? value) => string.IsNullOrEmpty(value); + + public static Task OpenInBrowserAsync(IWin32Window? owner, string url) + => MyCommon.OpenInBrowserAsync(owner, SettingManager.Local.BrowserPath, url); + + public static Task OpenInBrowserAsync(IWin32Window? owner, string? browserPath, string url) + { + return Task.Run(() => + { + try + { + var startInfo = MyCommon.CreateBrowserProcessStartInfo(browserPath, url); + Process.Start(startInfo); + } + catch (Win32Exception ex) + { + var message = string.Format(Properties.Resources.BrowserStartFailed, ex.ErrorCode); + MessageBox.Show(owner, message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + }); + } + + public static ProcessStartInfo CreateBrowserProcessStartInfo(string? browserPathWithArgs, string url) + { + if (MyCommon.IsNullOrEmpty(browserPathWithArgs)) + { + return new ProcessStartInfo + { + FileName = url, + UseShellExecute = true, + }; + } + + int quoteEnd = -1; + if (browserPathWithArgs.StartsWith("\"", StringComparison.Ordinal)) + quoteEnd = browserPathWithArgs.IndexOf("\"", 1, StringComparison.Ordinal); + + string browserPath, browserArgs; + var isQuoted = quoteEnd != -1; + if (isQuoted) + { + browserPath = browserPathWithArgs.Substring(1, quoteEnd - 1); + browserArgs = browserPathWithArgs.Substring(quoteEnd + 1).Trim(); + } + else + { + browserPath = browserPathWithArgs; + browserArgs = ""; + } + + var quotedUrl = "\"" + url.Replace("\"", "\\\"") + "\""; + var args = MyCommon.IsNullOrEmpty(browserArgs) ? quotedUrl : browserArgs + " " + quotedUrl; + + return new ProcessStartInfo + { + FileName = browserPath, + Arguments = args, + UseShellExecute = false, + + }; + } } } diff --git a/OpenTween/SearchWordDialog.cs b/OpenTween/SearchWordDialog.cs index f8eab67f1..de625be4f 100644 --- a/OpenTween/SearchWordDialog.cs +++ b/OpenTween/SearchWordDialog.cs @@ -211,9 +211,7 @@ private async void linkLabelSearchHelp_LinkClicked(object sender, LinkLabelLinkC { // 「検索オプションの使い方」ページのURL const string PublicSearchHelpUrl = "https://support.twitter.com/articles/249059"; - - var tweenMain = (TweenMain)this.Owner; - await tweenMain.OpenUriInBrowserAsync(PublicSearchHelpUrl); + await MyCommon.OpenInBrowserAsync(this, PublicSearchHelpUrl); } private void SearchWordDialog_KeyDown(object sender, KeyEventArgs e) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index d18e33c71..1e1c63ef7 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2170,7 +2170,7 @@ private async void PostButton_Click(object sender, EventArgs e) if (StatusText.Text.StartsWith("Google:", StringComparison.OrdinalIgnoreCase) && StatusText.Text.Trim().Length > 7) { var tmp = string.Format(Properties.Resources.SearchItem2Url, Uri.EscapeDataString(StatusText.Text.Substring(7))); - await this.OpenUriInBrowserAsync(tmp); + await MyCommon.OpenInBrowserAsync(this, tmp); } await this.PostMessageAsync(status, uploadService, uploadItems); @@ -2989,16 +2989,16 @@ private async void MoveToHomeToolStripMenuItem_Click(object sender, EventArgs e) { var post = this.CurrentPost; if (post != null) - await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl + post.ScreenName); + await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl + post.ScreenName); else - await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl); + await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl); } private async void MoveToFavToolStripMenuItem_Click(object sender, EventArgs e) { var post = this.CurrentPost; if (post != null) - await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl + "#!/" + post.ScreenName + "/favorites"); + await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl + "#!/" + post.ScreenName + "/favorites"); } private void TweenMain_ClientSizeChanged(object sender, EventArgs e) @@ -5315,7 +5315,7 @@ private async void StatusOpenMenuItem_Click(object sender, EventArgs e) var tab = this.CurrentTab; var post = this.CurrentPost; if (post != null && tab.TabType != MyCommon.TabUsageType.DirectMessage) - await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(post)); + await MyCommon.OpenInBrowserAsync(this, MyCommon.GetStatusUrl(post)); } private async void VerUpMenuItem_Click(object sender, EventArgs e) @@ -5413,7 +5413,7 @@ private async Task CheckNewVersion(bool startup = false) if (dialog.ShowDialog(this) == DialogResult.Yes) { - await this.OpenUriInBrowserAsync(versionInfo.DownloadUri.OriginalString); + await MyCommon.OpenInBrowserAsync(this, versionInfo.DownloadUri.OriginalString); } else if (dialog.SkipButtonPressed) { @@ -5524,10 +5524,10 @@ private async void MatomeMenuItem_Click(object sender, EventArgs e) => await this.OpenApplicationWebsite(); private async Task OpenApplicationWebsite() - => await this.OpenUriInBrowserAsync(ApplicationSettings.WebsiteUrl); + => await MyCommon.OpenInBrowserAsync(this, ApplicationSettings.WebsiteUrl); private async void ShortcutKeyListMenuItem_Click(object sender, EventArgs e) - => await this.OpenUriInBrowserAsync(ApplicationSettings.ShortcutKeyUrl); + => await MyCommon.OpenInBrowserAsync(this, ApplicationSettings.ShortcutKeyUrl); private async void ListTab_KeyDown(object sender, KeyEventArgs e) { @@ -6598,7 +6598,7 @@ await Task.Run(async () => catch (WebApiException ex) { this.StatusLabel.Text = $"Err:{ex.Message}(GetStatus)"; - await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(inReplyToUser, inReplyToId)); + await MyCommon.OpenInBrowserAsync(this, MyCommon.GetStatusUrl(inReplyToUser, inReplyToId)); return; } @@ -6607,7 +6607,7 @@ await Task.Run(async () => inReplyPost = inReplyToPosts.FirstOrDefault(); if (inReplyPost == null) { - await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(inReplyToUser, inReplyToId)); + await MyCommon.OpenInBrowserAsync(this, MyCommon.GetStatusUrl(inReplyToUser, inReplyToId)); return; } } @@ -8718,7 +8718,7 @@ private async Task doRepliedStatusOpen() { if (MyCommon.IsKeyDown(Keys.Shift)) { - await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(currentPost.InReplyToUser, currentPost.InReplyToStatusId.Value)); + await MyCommon.OpenInBrowserAsync(this, MyCommon.GetStatusUrl(currentPost.InReplyToUser, currentPost.InReplyToStatusId.Value)); return; } if (this._statuses.Posts.TryGetValue(currentPost.InReplyToStatusId.Value, out var repPost)) @@ -8734,7 +8734,7 @@ private async Task doRepliedStatusOpen() MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi); return; } - await this.OpenUriInBrowserAsync(MyCommon.GetStatusUrl(currentPost.InReplyToUser, currentPost.InReplyToStatusId.Value)); + await MyCommon.OpenInBrowserAsync(this, MyCommon.GetStatusUrl(currentPost.InReplyToUser, currentPost.InReplyToStatusId.Value)); } } } @@ -9350,7 +9350,7 @@ public async Task OpenUriAsync(Uri uri, bool isReverseSettings = false) } // どのパターンにも該当しないURL - await this.OpenUriInBrowserAsync(uriStr); + await MyCommon.OpenInBrowserAsync(this, uriStr); } /// @@ -9368,45 +9368,6 @@ private async Task OpenInternalUriAsync(Uri uri) } } - public Task OpenUriInBrowserAsync(string UriString) - { - return Task.Run(() => - { - var myPath = UriString; - - try - { - var configBrowserPath = SettingManager.Local.BrowserPath; - if (!MyCommon.IsNullOrEmpty(configBrowserPath)) - { - if (configBrowserPath.StartsWith("\"", StringComparison.Ordinal) && configBrowserPath.Length > 2 && configBrowserPath.IndexOf("\"", 2, StringComparison.Ordinal) > -1) - { - var sep = configBrowserPath.IndexOf("\"", 2, StringComparison.Ordinal); - var browserPath = configBrowserPath.Substring(1, sep - 1); - var arg = ""; - if (sep < configBrowserPath.Length - 1) - { - arg = configBrowserPath.Substring(sep + 1); - } - myPath = arg + " " + myPath; - System.Diagnostics.Process.Start(browserPath, myPath); - } - else - { - System.Diagnostics.Process.Start(configBrowserPath, myPath); - } - } - else - { - System.Diagnostics.Process.Start(myPath); - } - } - catch (Exception) - { - } - }); - } - private void ListTabSelect(TabPage _tab) { SetListProperty(); @@ -10284,7 +10245,7 @@ private async Task doMoveToRTHome() { var post = this.CurrentPost; if (post != null && post.RetweetedId != null) - await this.OpenUriInBrowserAsync("https://twitter.com/" + post.RetweetedBy); + await MyCommon.OpenInBrowserAsync(this, "https://twitter.com/" + post.RetweetedBy); } private async void MoveToRTHomeMenuItem_Click(object sender, EventArgs e) @@ -10963,7 +10924,7 @@ private void TweenRestartMenuItem_Click(object sender, EventArgs e) } private async void OpenOwnHomeMenuItem_Click(object sender, EventArgs e) - => await this.OpenUriInBrowserAsync(MyCommon.TwitterUrl + tw.Username); + => await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl + tw.Username); private bool ExistCurrentPost { @@ -11054,12 +11015,12 @@ private async Task OpenUserAppointUrl() var statusId = post.RetweetedId ?? post.StatusId; xUrl = xUrl.Replace("{STATUS}", statusId.ToString()); - await this.OpenUriInBrowserAsync(xUrl); + await MyCommon.OpenInBrowserAsync(this, xUrl); } } else { - await this.OpenUriInBrowserAsync(SettingManager.Common.UserAppointUrl); + await MyCommon.OpenInBrowserAsync(this, SettingManager.Common.UserAppointUrl); } } } @@ -11102,17 +11063,17 @@ private async void tweetThumbnail1_ThumbnailDoubleClick(object sender, Thumbnail => await this.OpenThumbnailPicture(e.Thumbnail); private async void tweetThumbnail1_ThumbnailImageSearchClick(object sender, ThumbnailImageSearchEventArgs e) - => await this.OpenUriInBrowserAsync(e.ImageUrl); + => await MyCommon.OpenInBrowserAsync(this, e.ImageUrl); private async Task OpenThumbnailPicture(ThumbnailInfo thumbnail) { var url = thumbnail.FullSizeImageUrl ?? thumbnail.MediaPageUrl; - await this.OpenUriInBrowserAsync(url); + await MyCommon.OpenInBrowserAsync(this, url); } private async void TwitterApiStatusToolStripMenuItem_Click(object sender, EventArgs e) - => await this.OpenUriInBrowserAsync(Twitter.ServiceAvailabilityStatusUrl); + => await MyCommon.OpenInBrowserAsync(this, Twitter.ServiceAvailabilityStatusUrl); private void PostButton_KeyDown(object sender, KeyEventArgs e) { diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 575cbd548..6f8533670 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -401,7 +401,7 @@ private async Task DoSearchToolStrip(string url) } var tmp = string.Format(url, Uri.EscapeDataString(_selText)); - await this.Owner.OpenUriInBrowserAsync(tmp); + await MyCommon.OpenInBrowserAsync(this, tmp); } } @@ -431,7 +431,7 @@ private async void UserPicture_DoubleClick(object sender, EventArgs e) if (this.CurrentPost == null) return; - await this.Owner.OpenUriInBrowserAsync(MyCommon.TwitterUrl + this.CurrentPost.ScreenName); + await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl + this.CurrentPost.ScreenName); } private void UserPicture_MouseEnter(object sender, EventArgs e) @@ -445,7 +445,7 @@ private async void PostBrowser_Navigated(object sender, WebBrowserNavigatedEvent if (e.Url.AbsoluteUri != "about:blank") { await this.ShowPostDetails(this.CurrentPost!); // 現在の発言を表示し直す (Navigated の段階ではキャンセルできない) - await this.Owner.OpenUriInBrowserAsync(e.Url.OriginalString); + await MyCommon.OpenInBrowserAsync(this, e.Url.OriginalString); } } @@ -519,7 +519,7 @@ private async void SourceLinkLabel_LinkClicked(object sender, LinkLabelLinkClick var sourceUri = this.CurrentPost?.SourceUri; if (sourceUri != null && e.Button == MouseButtons.Left) { - await this.Owner.OpenUriInBrowserAsync(sourceUri.AbsoluteUri); + await MyCommon.OpenInBrowserAsync(this, sourceUri.AbsoluteUri); } } @@ -695,7 +695,7 @@ private async void IconNameToolStripMenuItem_Click(object sender, EventArgs e) if (MyCommon.IsNullOrEmpty(imageUrl)) return; - await this.Owner.OpenUriInBrowserAsync(imageUrl.Remove(imageUrl.LastIndexOf("_normal", StringComparison.Ordinal), 7)); // "_normal".Length + await MyCommon.OpenInBrowserAsync(this, imageUrl.Remove(imageUrl.LastIndexOf("_normal", StringComparison.Ordinal), 7)); // "_normal".Length } private async void ReloadIconToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/OpenTween/UserInfoDialog.cs b/OpenTween/UserInfoDialog.cs index 24370be0b..8a35cbb9c 100644 --- a/OpenTween/UserInfoDialog.cs +++ b/OpenTween/UserInfoDialog.cs @@ -345,7 +345,7 @@ private async void LinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEven if (linkUrl == null) return; - await this.mainForm.OpenUriInBrowserAsync(linkUrl); + await MyCommon.OpenInBrowserAsync(this, linkUrl); } private async void ButtonFollow_Click(object sender, EventArgs e) @@ -450,10 +450,10 @@ private void ContextMenuRecentPostBrowser_Opening(object sender, CancelEventArgs } private async void LinkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - => await this.mainForm.OpenUriInBrowserAsync("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"); + => 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"); private async void LinkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - => await this.mainForm.OpenUriInBrowserAsync("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"); + => 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"); private async void ButtonSearchPosts_Click(object sender, EventArgs e) => await this.mainForm.AddNewTabForUserTimeline(this._displayUser.ScreenName); @@ -463,7 +463,7 @@ private async void UserPicture_Click(object sender, EventArgs e) var imageUrl = this._displayUser.ProfileImageUrlHttps; imageUrl = imageUrl.Remove(imageUrl.LastIndexOf("_normal", StringComparison.Ordinal), 7); - await this.mainForm.OpenUriInBrowserAsync(imageUrl); + await MyCommon.OpenInBrowserAsync(this, imageUrl); } private bool IsEditing = false; From ece0a6682db922600d195a6a04a05751dae1be5b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 31 Jan 2022 00:14:09 +0900 Subject: [PATCH 050/402] =?UTF-8?q?AuthDialog=E3=81=AB=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=82=8B=E8=AA=8D=E5=8F=AFURL=E3=82=92?= =?UTF-8?q?=E3=82=B3=E3=83=94=E3=83=BC=E3=81=99=E3=82=8B=E6=89=8B=E6=AE=B5?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit URLの関連付けの問題などでブラウザが起動できずアカウントを追加できない場合がある問題の緩和策 --- OpenTween/AuthDialog.Designer.cs | 21 +++++++++++++++++++++ OpenTween/AuthDialog.cs | 14 ++++++++++++++ OpenTween/AuthDialog.en.resx | 5 +++-- OpenTween/AuthDialog.resx | 26 +++++++++++++++++--------- OpenTween/Resources/ChangeLog.txt | 1 + 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/OpenTween/AuthDialog.Designer.cs b/OpenTween/AuthDialog.Designer.cs index c765830e9..d4479fe9e 100644 --- a/OpenTween/AuthDialog.Designer.cs +++ b/OpenTween/AuthDialog.Designer.cs @@ -28,14 +28,18 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { + this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AuthDialog)); this.label1 = new System.Windows.Forms.Label(); this.AuthLinkLabel = new System.Windows.Forms.LinkLabel(); + this.contextMenuLinkLabel = new System.Windows.Forms.ContextMenuStrip(this.components); + this.MenuItemCopyURL = new System.Windows.Forms.ToolStripMenuItem(); this.label2 = new System.Windows.Forms.Label(); this.PinTextBox = new System.Windows.Forms.TextBox(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.CancelBtn = new System.Windows.Forms.Button(); this.OKBtn = new System.Windows.Forms.Button(); + this.contextMenuLinkLabel.SuspendLayout(); this.tableLayoutPanel1.SuspendLayout(); this.SuspendLayout(); // @@ -47,11 +51,25 @@ private void InitializeComponent() // AuthLinkLabel // this.AuthLinkLabel.AutoEllipsis = true; + this.AuthLinkLabel.ContextMenuStrip = this.contextMenuLinkLabel; resources.ApplyResources(this.AuthLinkLabel, "AuthLinkLabel"); this.AuthLinkLabel.Name = "AuthLinkLabel"; this.AuthLinkLabel.TabStop = true; this.AuthLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.AuthLinkLabel_LinkClicked); // + // contextMenuLinkLabel + // + this.contextMenuLinkLabel.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.MenuItemCopyURL}); + this.contextMenuLinkLabel.Name = "contextMenuLinkLabel"; + resources.ApplyResources(this.contextMenuLinkLabel, "contextMenuLinkLabel"); + // + // MenuItemCopyURL + // + this.MenuItemCopyURL.Name = "MenuItemCopyURL"; + resources.ApplyResources(this.MenuItemCopyURL, "MenuItemCopyURL"); + this.MenuItemCopyURL.Click += new System.EventHandler(this.MenuItemCopyURL_Click); + // // label2 // resources.ApplyResources(this.label2, "label2"); @@ -99,6 +117,7 @@ private void InitializeComponent() this.Name = "AuthDialog"; this.ShowIcon = false; this.ShowInTaskbar = false; + this.contextMenuLinkLabel.ResumeLayout(false); this.tableLayoutPanel1.ResumeLayout(false); this.tableLayoutPanel1.PerformLayout(); this.ResumeLayout(false); @@ -115,5 +134,7 @@ private void InitializeComponent() private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private System.Windows.Forms.Button CancelBtn; private System.Windows.Forms.Button OKBtn; + private System.Windows.Forms.ContextMenuStrip contextMenuLinkLabel; + private System.Windows.Forms.ToolStripMenuItem MenuItemCopyURL; } } \ No newline at end of file diff --git a/OpenTween/AuthDialog.cs b/OpenTween/AuthDialog.cs index c861999fa..06a03f84c 100644 --- a/OpenTween/AuthDialog.cs +++ b/OpenTween/AuthDialog.cs @@ -27,6 +27,7 @@ using System.Data; using System.Drawing; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; @@ -59,10 +60,23 @@ public string Pin private async void AuthLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { + // 右クリックの場合は無視する + if (e.Button == MouseButtons.Right) + return; + AuthLinkLabel.LinkVisited = true; await MyCommon.OpenInBrowserAsync(this, this.AuthUrl); } + private void MenuItemCopyURL_Click(object sender, EventArgs e) + { + try + { + Clipboard.SetText(this.AuthUrl); + } + catch (ExternalException) { } + } + /// /// 指定されたURLにユーザーがアクセスするように指示してPINを入力させるだけ /// diff --git a/OpenTween/AuthDialog.en.resx b/OpenTween/AuthDialog.en.resx index c69ce4891..86d01655f 100644 --- a/OpenTween/AuthDialog.en.resx +++ b/OpenTween/AuthDialog.en.resx @@ -4,13 +4,14 @@ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - NoControl &Cancel + 126, 26 190, 12 Access URL bellow in your browser: 176, 12 Allow the app and input your PIN: + 125, 22 + &Copy URL PIN Code diff --git a/OpenTween/AuthDialog.resx b/OpenTween/AuthDialog.resx index fb4f2a68a..9885a533b 100644 --- a/OpenTween/AuthDialog.resx +++ b/OpenTween/AuthDialog.resx @@ -13,23 +13,27 @@ CenterScreen AuthDialog AuthDialog - OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + OpenTween.OTBaseForm, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null AuthLinkLabel $this System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 3 + 4 CancelBtn tableLayoutPanel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 0 + contextMenuLinkLabel + System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 label1 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 4 + 5 label2 $this System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 2 + 3 + MenuItemCopyURL + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 OKBtn tableLayoutPanel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -37,11 +41,11 @@ PinTextBox $this System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 + 2 tableLayoutPanel1 $this System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 0 + 1 24, 69 15, 15, 15, 15 396, 15 @@ -52,19 +56,23 @@ 86, 25 1 キャンセル (&C) + 148, 26 + 17, 17 True 12, 24 3, 15, 3, 15 - 359, 15 + 352, 12 0 下記のURLにブラウザでアクセスし、内容を確認の上で認証を行って下さい: True 12, 114 3, 15, 3, 15 - 232, 15 + 228, 12 2 認証後に表示されるPINコードを入力して下さい + 147, 22 + URLをコピー (&C) True 3, 3 75, 25 @@ -74,7 +82,7 @@ Top, Left, Right MS UI Gothic, 24pt 127, 147 - 190, 48 + 190, 39 3 Center Bottom, Right diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index daf62962a..961e66356 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Ver 2.4.4-dev(2019/xx/xx) + * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 * CHG: Instagramのサムネイルを表示するURLのパターンを追加 * CHG: YouTubeのサムネイルを表示するURLのパターンを追加 (thx @Hawklaver!) From 87d6aeec846657bca02ac3dccbc79e7307db0b6e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 1 Feb 2022 01:27:28 +0900 Subject: [PATCH 051/402] =?UTF-8?q?=E8=AA=8D=E5=8F=AFURL=E3=82=92=E9=96=8B?= =?UTF-8?q?=E3=81=8F=E9=9A=9B=E3=81=AB=E6=9C=AA=E4=BF=9D=E5=AD=98=E3=81=AE?= =?UTF-8?q?=E3=83=96=E3=83=A9=E3=82=A6=E3=82=B6=E3=83=91=E3=82=B9=E3=81=AE?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=82=92=E9=81=A9=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/AppendSettingDialog.cs | 3 ++- OpenTween/AuthDialog.cs | 8 ++++++-- OpenTween/Resources/ChangeLog.txt | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index ed774d177..c6b60b59f 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -271,7 +271,8 @@ public void ApplyNetworkSettings() var pinPageUrl = TwitterApiConnection.GetAuthorizeUri(requestToken); - var pin = AuthDialog.DoAuth(this, pinPageUrl); + var browserPath = this.ActionPanel.BrowserPathText.Text; + var pin = AuthDialog.DoAuth(this, pinPageUrl, browserPath); if (MyCommon.IsNullOrEmpty(pin)) return null; // キャンセルされた場合 diff --git a/OpenTween/AuthDialog.cs b/OpenTween/AuthDialog.cs index 06a03f84c..7cf1c7171 100644 --- a/OpenTween/AuthDialog.cs +++ b/OpenTween/AuthDialog.cs @@ -58,6 +58,8 @@ public string Pin set => PinTextBox.Text = value; } + public string? BrowserPath { get; set; } + private async void AuthLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { // 右クリックの場合は無視する @@ -65,7 +67,7 @@ private async void AuthLinkLabel_LinkClicked(object sender, LinkLabelLinkClicked return; AuthLinkLabel.LinkVisited = true; - await MyCommon.OpenInBrowserAsync(this, this.AuthUrl); + await MyCommon.OpenInBrowserAsync(this, this.BrowserPath, this.AuthUrl); } private void MenuItemCopyURL_Click(object sender, EventArgs e) @@ -82,11 +84,13 @@ private void MenuItemCopyURL_Click(object sender, EventArgs e) /// /// 親ウィンドウ /// 認証URL + /// Webブラウザのパス /// PIN文字列 - public static string? DoAuth(IWin32Window owner, Uri authUri) + public static string? DoAuth(IWin32Window owner, Uri authUri, string? browserPath) { using var dialog = new AuthDialog(); dialog.AuthUrl = authUri.AbsoluteUri; + dialog.BrowserPath = browserPath; dialog.ShowDialog(owner); diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 961e66356..2d38ddef5 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -13,6 +13,7 @@ * CHG: POSTキーのデフォルト設定を Ctrl+Enter に変更 * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) + * FIX: 初回起動時の設定画面でブラウザパスを入力しても認可URLを開く際に適用されない不具合を修正 ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 From 2af0414bf4a94069c4eb548b20ae871a6eeade72 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 30 Jan 2022 16:18:29 +0900 Subject: [PATCH 052/402] =?UTF-8?q?=E3=80=8CURL=E8=87=AA=E5=8B=95=E7=9F=AD?= =?UTF-8?q?=E7=B8=AE=E3=81=A7=E5=84=AA=E5=85=88=E7=9A=84=E3=81=AB=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=80=8D=E3=81=8C=E5=AE=9F=E9=9A=9B=E3=81=AE=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E5=80=A4=E3=81=AE=E9=80=9A=E3=82=8A=E3=81=AB=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84=E4=B8=8D=E5=85=B7?= =?UTF-8?q?=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: d5c55f46 ("廃止された twurl.nl によるURL短縮機能を削除") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Setting/Panel/ShortUrlPanel.Designer.cs | 3 +-- OpenTween/Setting/Panel/ShortUrlPanel.resx | 7 +++---- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 2d38ddef5..3188c9a1c 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -14,6 +14,7 @@ * FIX: DMの添付画像をブラウザで開く場合に使用するURLを変更 * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) * FIX: 初回起動時の設定画面でブラウザパスを入力しても認可URLを開く際に適用されない不具合を修正 + * FIX: URL自動短縮の設定値が正しく表示されない不具合を修正 ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 diff --git a/OpenTween/Setting/Panel/ShortUrlPanel.Designer.cs b/OpenTween/Setting/Panel/ShortUrlPanel.Designer.cs index bf20d8ac4..1e3843faa 100644 --- a/OpenTween/Setting/Panel/ShortUrlPanel.Designer.cs +++ b/OpenTween/Setting/Panel/ShortUrlPanel.Designer.cs @@ -77,8 +77,7 @@ private void InitializeComponent() resources.GetString("ComboBoxAutoShortUrlFirst.Items1"), resources.GetString("ComboBoxAutoShortUrlFirst.Items2"), resources.GetString("ComboBoxAutoShortUrlFirst.Items3"), - resources.GetString("ComboBoxAutoShortUrlFirst.Items4"), - resources.GetString("ComboBoxAutoShortUrlFirst.Items5")}); + resources.GetString("ComboBoxAutoShortUrlFirst.Items4")}); resources.ApplyResources(this.ComboBoxAutoShortUrlFirst, "ComboBoxAutoShortUrlFirst"); this.ComboBoxAutoShortUrlFirst.Name = "ComboBoxAutoShortUrlFirst"; this.ComboBoxAutoShortUrlFirst.SelectedIndexChanged += new System.EventHandler(this.ComboBoxAutoShortUrlFirst_SelectedIndexChanged); diff --git a/OpenTween/Setting/Panel/ShortUrlPanel.resx b/OpenTween/Setting/Panel/ShortUrlPanel.resx index d4a9b05ac..a29d3f246 100644 --- a/OpenTween/Setting/Panel/ShortUrlPanel.resx +++ b/OpenTween/Setting/Panel/ShortUrlPanel.resx @@ -62,10 +62,9 @@ 短縮URLを解決する tinyurl is.gd - twurl.nl - bit.ly - j.mp - ux.nu + bit.ly + j.mp + ux.nu 249, 98 246, 20 4 From 3404d4bc9e0faba74245e73cc4805fe09fa2cc77 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 1 Feb 2022 04:43:12 +0900 Subject: [PATCH 053/402] =?UTF-8?q?BasedPanel=E3=81=AE=E3=83=AC=E3=82=A4?= =?UTF-8?q?=E3=82=A2=E3=82=A6=E3=83=88=E3=81=8C=E9=AB=98DPI=E7=92=B0?= =?UTF-8?q?=E5=A2=83=E3=81=A7=E5=B4=A9=E3=82=8C=E3=82=8B=E5=95=8F=E9=A1=8C?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit panel1 は Anchor に Right を指定しているコントロールが高 DPI 環境下で正しくスケーリングされない問題の回避に必要 --- .../Setting/Panel/BasedPanel.Designer.cs | 22 +++++++++---- OpenTween/Setting/Panel/BasedPanel.resx | 32 ++++++++++++------- 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/OpenTween/Setting/Panel/BasedPanel.Designer.cs b/OpenTween/Setting/Panel/BasedPanel.Designer.cs index 92465f317..88c42afc9 100644 --- a/OpenTween/Setting/Panel/BasedPanel.Designer.cs +++ b/OpenTween/Setting/Panel/BasedPanel.Designer.cs @@ -34,6 +34,8 @@ private void InitializeComponent() this.StartAuthButton = new System.Windows.Forms.Button(); this.AuthClearButton = new System.Windows.Forms.Button(); this.Label4 = new System.Windows.Forms.Label(); + this.panel1 = new System.Windows.Forms.Panel(); + this.panel1.SuspendLayout(); this.SuspendLayout(); // // AuthUserCombo @@ -67,18 +69,25 @@ private void InitializeComponent() resources.ApplyResources(this.Label4, "Label4"); this.Label4.Name = "Label4"; // + // panel1 + // + this.panel1.Controls.Add(this.AuthUserCombo); + this.panel1.Controls.Add(this.CreateAccountButton); + this.panel1.Controls.Add(this.StartAuthButton); + this.panel1.Controls.Add(this.AuthClearButton); + this.panel1.Controls.Add(this.Label4); + resources.ApplyResources(this.panel1, "panel1"); + this.panel1.Name = "panel1"; + // // BasedPanel // resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.Controls.Add(this.AuthUserCombo); - this.Controls.Add(this.CreateAccountButton); - this.Controls.Add(this.StartAuthButton); - this.Controls.Add(this.AuthClearButton); - this.Controls.Add(this.Label4); + this.Controls.Add(this.panel1); this.Name = "BasedPanel"; + this.panel1.ResumeLayout(false); + this.panel1.PerformLayout(); this.ResumeLayout(false); - this.PerformLayout(); } @@ -89,5 +98,6 @@ private void InitializeComponent() internal System.Windows.Forms.Button StartAuthButton; internal System.Windows.Forms.Button AuthClearButton; internal System.Windows.Forms.Label Label4; + private System.Windows.Forms.Panel panel1; } } diff --git a/OpenTween/Setting/Panel/BasedPanel.resx b/OpenTween/Setting/Panel/BasedPanel.resx index b3535e03a..7d65746a2 100644 --- a/OpenTween/Setting/Panel/BasedPanel.resx +++ b/OpenTween/Setting/Panel/BasedPanel.resx @@ -9,53 +9,63 @@ 96, 96 True + 0, 0, 0, 0 BasedPanel - OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + OpenTween.Setting.Panel.SettingPanelBase, OpenTween, Version=2.4.3.1, Culture=neutral, PublicKeyToken=null AuthClearButton - $this + panel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 3 AuthUserCombo - $this + panel1 System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 0 CreateAccountButton - $this + panel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 Label4 - $this + panel1 System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 4 + panel1 + $this + System.Windows.Forms.Panel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 StartAuthButton - $this + panel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 2 True NoControl 293, 20 75, 25 - 9 + 2 削除 111, 22 160, 20 - 8 + 1 Bottom, Right True NoControl 310, 320 186, 25 - 11 + 4 Twitter アカウントを作成する True NoControl 23, 25 49, 12 - 7 + 0 アカウント + Fill + 0, 0 + 20, 20, 20, 20 + 519, 368 + 0 NoControl 98, 63 321, 45 - 10 + 3 認証開始 From 281727660a4c49c93ceae35671634b57a50a1f48 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 1 Feb 2022 23:42:30 +0900 Subject: [PATCH 054/402] =?UTF-8?q?ApplicationSettings=E3=81=AB=E9=96=8B?= =?UTF-8?q?=E7=99=BA=E7=94=A8=E3=81=AEAPI=E3=82=AD=E3=83=BC=E3=82=92?= =?UTF-8?q?=E3=82=BB=E3=83=83=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationSettings.cs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/OpenTween/ApplicationSettings.cs b/OpenTween/ApplicationSettings.cs index e65f3bcf5..589db3c34 100644 --- a/OpenTween/ApplicationSettings.cs +++ b/OpenTween/ApplicationSettings.cs @@ -120,12 +120,12 @@ internal static class ApplicationSettings /// /// Twitter API Key /// - public static readonly ApiKey TwitterConsumerKey = ApiKey.Create("zIoJPq3FsuViPTAs89FetDHYz"); + public static readonly ApiKey TwitterConsumerKey = ApiKey.Create("%e%lhBzdIOsT0NwiaraGF6M8Q==%DtKV/SIVVVGA0tnaubpG0c5VL52DtkndCd5bYNPfQ/M=%4pkaNg/LhtyFPUlhMG9v+2DWuYxlYZSB9md5J/azJbA="); /// /// Twitter API Key Secret /// - public static readonly ApiKey TwitterConsumerSecret = ApiKey.Create("prTAs2fqLv12nHxlMoLQZT8AkpZt0yYb8A7ktGS2VYeRj0TddS"); + public static readonly ApiKey TwitterConsumerSecret = ApiKey.Create("%e%qYUFwFZCk/oYRwkF+d5G1A==%wqJcbfvhm3avxQaFha6hjLZkuo07y0EOUzOfT66NyuR4KOe5V3Jgvw6Kvy5V/VKafZHmq8j6xyKzytQQa7kpUw==%VgfPeI7XK/zhds2Tk/QTo5hPe2/4rRsGnLascX5Lp1I="); //===================================================================== // Foursquare @@ -134,12 +134,12 @@ internal static class ApplicationSettings /// /// Foursquare Client Id /// - public static readonly ApiKey FoursquareClientId = ApiKey.Create("5H3K5YQPT55DNQUFEOAJFNJA5D01ZJGO2ITEAJ3ASRIDONUB"); + public static readonly ApiKey FoursquareClientId = ApiKey.Create("%e%V/zwwnhz2ubgeXExKHm+0Q==%6QVbfha2Mzj0jgfI53jtup5sTov1T36BDdb6Bj3WeceHY/D3/7ZcqIlgIM/9ao6ZK/UWVq2iedgP826JnHL8Mg==%JROQDGrJaw6g4uFUO0SC/sgYgyXhbE/N82zJvYoOx+A="); /// /// Foursquare Client Secret /// - public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("JFRHP1L451M3AEPF11UZLTIIUZCZTZRVHVOWB5TQ0AJOVPBB"); + public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("%e%OHLwPR511lrD5I/7q3uwZA==%Qr1q996MLlPhlo0tWCNHsU44sU1Q8MCO23I/fWkJE/gQha1RpEVcrdRXIiCzNC/Z3dKPSZZvPxinOCjOIDTSUw==%NPBn8TnvT24FAPZvAnwhNFGXZ+MB3YCZ6QLplivNtDE="); //===================================================================== // bit.ly @@ -148,12 +148,12 @@ internal static class ApplicationSettings /// /// bit.ly Client ID /// - public static readonly ApiKey BitlyClientId = ApiKey.Create("ddab8ec50f4459c315cbde9d923cf490923b6d2e"); + public static readonly ApiKey BitlyClientId = ApiKey.Create("%e%D6d+cV9roc9oRyFHlzzpNA==%5PU2keurc+lfK56rsbEftpHz9S/X4xVg8vRKLXHksspOtOeLXHlR55XdPX4vafIr%X5bBNiqWcqeIThNZmDkz3rM2ObtIYPqVV5ijCg4rlME="); /// /// bit.ly Client Secret /// - public static readonly ApiKey BitlyClientSecret = ApiKey.Create("485c9d03dd264f8eeb4fc65d38e2762c4420cee7"); + public static readonly ApiKey BitlyClientSecret = ApiKey.Create("%e%p3whdM7O13e3Wos1EBCgZg==%uaZQscha5IYHVIwedXo4klPBMxzyFmJwB4cO3+hzTVm7KGhnxsHh44aoLfLTzuzI%mqFsvWt7k7ps2HcCjxwbZS66lGcFHae1rG6XWjxMqfY="); //===================================================================== // TINAMI @@ -162,7 +162,7 @@ internal static class ApplicationSettings /// /// TINAMI APIキー /// - public static readonly ApiKey TINAMIApiKey = ApiKey.Create("4f48bb4858d36"); + public static readonly ApiKey TINAMIApiKey = ApiKey.Create("%e%7hQ5WcIjLOahw9VNyIU4qA==%z/T24upQAfNub0WiMrxLjg==%Mh+7SC+8SR514jm8tSgrRqn70i+psuox5dyQ5cHh7zs="); //===================================================================== // Microsoft Translator API (Cognitive Service) @@ -171,7 +171,7 @@ internal static class ApplicationSettings /// /// Translator Text API Subscription Key /// - public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("6c47d2ea341148bf856bdbfafd429db7"); + public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("%e%Ga0nDykCVBaQqG3i4Up2lg==%4YOYlRN+SOB7exH/9NFwyMMJzuiRgPWIk5tNNXOmq1+OVcjUpz9McAlzs6zx8/7D%iX+okw1Wq5um+U3ioZacoTbYVsB9tWGmqu7r2vDtmxY="); //===================================================================== // Imgur @@ -180,12 +180,12 @@ internal static class ApplicationSettings /// /// Imgur Client ID /// - public static readonly ApiKey ImgurClientId = ApiKey.Create("a5fff36fb83568c"); + public static readonly ApiKey ImgurClientId = ApiKey.Create("%e%f7UHH6fRBgLN6pxmjiiEWg==%vO2rqQQv9tQDeaTJX9FSyg==%98vuz4Pd1lN/HvbtzPG4x8yZcB+aKZjvRSKjvbe+kuA="); /// /// Imgur Client Secret /// - public static readonly ApiKey ImgurClientSecret = ApiKey.Create("af5d668a9aa83b34a8f0f735e12073edafbc9a5d"); + public static readonly ApiKey ImgurClientSecret = ApiKey.Create("%e%mc+eebhAF+zJXPN8Pb6pgQ==%zNuPAx+sT32l1Aank7nZk5YlXLWsLC0tCg/ac09dHe+nO0pBoVQtQ0z6C825olJE%NIaCwpyNvwmj1fsYtgp4i7xfMBYhzyf4mo6wTcTKssQ="); //===================================================================== // Mobypicture @@ -194,7 +194,7 @@ internal static class ApplicationSettings /// /// Mobypicture Developer Key /// - public static readonly ApiKey MobypictureKey = ApiKey.Create("quPWTX0UrPHxqdH7"); + public static readonly ApiKey MobypictureKey = ApiKey.Create("%e%gQlFICkgKMP5bZ15DfOFzQ==%n+3Dfxy4IMtFNljJgdDLuoh1MdzLAk6/ZsKdGugy3BA=%yuM7lNI8qFWYj6ppDdM2bC9EtHO+ms1G6vl9xTjijek="); //===================================================================== // Tumblr @@ -203,6 +203,6 @@ internal static class ApplicationSettings /// /// Tumblr OAuth Consumer Key /// - public static readonly ApiKey TumblrConsumerKey = ApiKey.Create("Nsk62V6wMIqVNbiGyN0g3aDGBlgU7Fcb9GJ8Se0z2MUDHAY15l"); + public static readonly ApiKey TumblrConsumerKey = ApiKey.Create("%e%WJZTGDwe4njFpgKGQi5jRg==%gY2QO1so6QOfWitwxYP8XbIp98AtN3tDtoK4Q6bUOePkXVlhr4uE/VxhMg56Nblxt34Zy/8hpQSi0hlhuS2drQ==%hGKO3RVp0WaT3coVbo3H65r2pmKB8TTuiIbBzAzaV1A="); } } From 6bc8095c44748576ab8e797ce5f82131066b8ea8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 2 Feb 2022 01:28:16 +0900 Subject: [PATCH 055/402] =?UTF-8?q?RelatedPostsTabModel=E3=81=A7=E4=B8=80?= =?UTF-8?q?=E9=83=A8=E3=81=AE=E3=83=84=E3=82=A4=E3=83=BC=E3=83=88=E3=81=A7?= =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=8C=E7=99=BA=E7=94=9F=E3=81=97?= =?UTF-8?q?=E3=81=A6=E3=82=82=E3=82=BF=E3=83=96=E3=81=AE=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E3=82=92=E7=B6=9A=E8=A1=8C=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Models/RelatedPostsTabModel.cs | 18 ++++++++++++------ OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 2 +- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/OpenTween/Models/RelatedPostsTabModel.cs b/OpenTween/Models/RelatedPostsTabModel.cs index 5575f2387..be635dc19 100644 --- a/OpenTween/Models/RelatedPostsTabModel.cs +++ b/OpenTween/Models/RelatedPostsTabModel.cs @@ -62,14 +62,20 @@ public override async Task RefreshAsync(Twitter tw, bool _, bool startup, IProgr else read = startup && SettingManager.Common.Read; - progress.Report("Related refreshing..."); + try + { + progress.Report("Related refreshing..."); - await tw.GetRelatedResult(read, this) - .ConfigureAwait(false); + await tw.GetRelatedResult(read, this) + .ConfigureAwait(false); - TabInformations.GetInstance().DistributePosts(); - - progress.Report("Related refreshed"); + progress.Report("Related refreshed"); + } + finally + { + // WebException が発生した場合も一部のツイートは読み込めている可能性があるため常に DistoributePosts を呼ぶ + TabInformations.GetInstance().DistributePosts(); + } } } } diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 3188c9a1c..86de1b2f5 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -15,6 +15,7 @@ * FIX: 大文字アルファベットを含むハッシュタグがユーザー情報画面で正しくリンク化されない不具合を修正 (thx @naminodarie!) * FIX: 初回起動時の設定画面でブラウザパスを入力しても認可URLを開く際に適用されない不具合を修正 * FIX: URL自動短縮の設定値が正しく表示されない不具合を修正 + * FIX: 関連発言表示で一部のツイートの読み込みがエラーになると関連発言タブに何も表示されなくなる不具合を修正 ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 1e1c63ef7..52ad95cbf 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2257,7 +2257,6 @@ private async Task RefreshTabAsync(TabModel tab, bool backward) { this.RefreshTasktrayIcon(); await Task.Run(() => tab.RefreshAsync(this.tw, backward, this._initial, this.workerProgress)); - this.RefreshTimeline(); } catch (WebApiException ex) { @@ -2278,6 +2277,7 @@ private async Task RefreshTabAsync(TabModel tab, bool backward) } finally { + this.RefreshTimeline(); this.workerSemaphore.Release(); } } From df9c338f7aaed2a31ae45721e6e7c7c9c378cb7b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 2 Feb 2022 02:18:48 +0900 Subject: [PATCH 056/402] =?UTF-8?q?=E9=96=8B=E7=99=BA=E7=94=A8=E3=81=AEAPI?= =?UTF-8?q?=E3=82=AD=E3=83=BC=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationSettings.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenTween/ApplicationSettings.cs b/OpenTween/ApplicationSettings.cs index 589db3c34..2ce610626 100644 --- a/OpenTween/ApplicationSettings.cs +++ b/OpenTween/ApplicationSettings.cs @@ -134,12 +134,12 @@ internal static class ApplicationSettings /// /// Foursquare Client Id /// - public static readonly ApiKey FoursquareClientId = ApiKey.Create("%e%V/zwwnhz2ubgeXExKHm+0Q==%6QVbfha2Mzj0jgfI53jtup5sTov1T36BDdb6Bj3WeceHY/D3/7ZcqIlgIM/9ao6ZK/UWVq2iedgP826JnHL8Mg==%JROQDGrJaw6g4uFUO0SC/sgYgyXhbE/N82zJvYoOx+A="); + public static readonly ApiKey FoursquareClientId = ApiKey.Create("%e%PUhzXizCMlOCLv6AjDEwWw==%p6wCukrAWVmPv+mevyhIBJsTmld+nN8jqqdcrUM2bnqvVU9+W1V9rtMrM19Ew2A2Uw2N7yPAmymR6YgVxO5hZw==%PcIbp7rt0Bom/igLAbOR5TwIfdF7Ucej4+tCQuZ7ALE="); /// /// Foursquare Client Secret /// - public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("%e%OHLwPR511lrD5I/7q3uwZA==%Qr1q996MLlPhlo0tWCNHsU44sU1Q8MCO23I/fWkJE/gQha1RpEVcrdRXIiCzNC/Z3dKPSZZvPxinOCjOIDTSUw==%NPBn8TnvT24FAPZvAnwhNFGXZ+MB3YCZ6QLplivNtDE="); + public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("%e%MfvV15MhI4znNalkQLKGUA==%ONIAN5e6ZUeCeAqFl6rkDIZWvKT9xEUA7S2c6H5KVs6Ba8p0fzxKnH+ay1x/awpjtTRtfkY7d8dOwouxEJJviQ==%WvG6oTGYIvUpKGyofIdAcP5jVTC7oLuK8KB7aT4U9vA="); //===================================================================== // bit.ly @@ -171,7 +171,7 @@ internal static class ApplicationSettings /// /// Translator Text API Subscription Key /// - public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("%e%Ga0nDykCVBaQqG3i4Up2lg==%4YOYlRN+SOB7exH/9NFwyMMJzuiRgPWIk5tNNXOmq1+OVcjUpz9McAlzs6zx8/7D%iX+okw1Wq5um+U3ioZacoTbYVsB9tWGmqu7r2vDtmxY="); + public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("%e%OftqWcavvEFL3ecdcE80KQ==%B/u2U2A84zfhHPV2MARqDTD0YPFruSgdOdP1+JqRaAAg5gEpTjCQfzr7noDN8YCa%73W3WtAt4e9G4HRou2Zu9s/D5cIQ8ccxDsv60KnLvWA="); //===================================================================== // Imgur @@ -180,12 +180,12 @@ internal static class ApplicationSettings /// /// Imgur Client ID /// - public static readonly ApiKey ImgurClientId = ApiKey.Create("%e%f7UHH6fRBgLN6pxmjiiEWg==%vO2rqQQv9tQDeaTJX9FSyg==%98vuz4Pd1lN/HvbtzPG4x8yZcB+aKZjvRSKjvbe+kuA="); + public static readonly ApiKey ImgurClientId = ApiKey.Create("%e%+ncaqKgmWPsHj8vm9vuR0A==%sw2Vvu3QQAFqqUU9FTGeRQ==%3cJIVrvCot+8LU4/l9iYQtsjn3dUYOdere56VsQIpNU="); /// /// Imgur Client Secret /// - public static readonly ApiKey ImgurClientSecret = ApiKey.Create("%e%mc+eebhAF+zJXPN8Pb6pgQ==%zNuPAx+sT32l1Aank7nZk5YlXLWsLC0tCg/ac09dHe+nO0pBoVQtQ0z6C825olJE%NIaCwpyNvwmj1fsYtgp4i7xfMBYhzyf4mo6wTcTKssQ="); + public static readonly ApiKey ImgurClientSecret = ApiKey.Create("%e%p3wLXhBzIpGOBpYn0w5G4w==%y0UO+MKvGnebqWJd6nKLifBYecFc9i4Bdf6n5+SuDEoGFSaDF54zCeRvJ8pVk9DF%LY6jZ/duMjRprZSR0qiIj/dentKm7AtLMjQq17mdlCg="); //===================================================================== // Mobypicture From e383a245a9fc7a13c7c874bc8848e9495620afed Mon Sep 17 00:00:00 2001 From: Quin <=> Date: Wed, 2 Feb 2022 11:14:03 -0700 Subject: [PATCH 057/402] Fixed typo and grammar. Behavier -> behavior. Doubleclick -> double clicking. --- OpenTween/Setting/Panel/ActionPanel.en.resx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenTween/Setting/Panel/ActionPanel.en.resx b/OpenTween/Setting/Panel/ActionPanel.en.resx index 69d6c4a86..030e3596f 100644 --- a/OpenTween/Setting/Panel/ActionPanel.en.resx +++ b/OpenTween/Setting/Panel/ActionPanel.en.resx @@ -24,7 +24,7 @@ 405, 12 Sounds will play when you enable this option and set sound file for each tabs. 183, 12 - Behavier when doubleclick a tweet + Behavior when double clicking a tweet 88, 12 Path to Browser 484, 12 From fb4688fc7a2b0e40d554ba2eb733a60cd86bc929 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 4 Feb 2022 06:02:48 +0900 Subject: [PATCH 058/402] =?UTF-8?q?ChangeLog=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e383a245a9fc7a13c7c874bc8848e9495620afed の変更を反映 --- OpenTween/Resources/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 86de1b2f5..aa5692197 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -16,6 +16,7 @@ * FIX: 初回起動時の設定画面でブラウザパスを入力しても認可URLを開く際に適用されない不具合を修正 * FIX: URL自動短縮の設定値が正しく表示されない不具合を修正 * FIX: 関連発言表示で一部のツイートの読み込みがエラーになると関連発言タブに何も表示されなくなる不具合を修正 + * FIX: 英語版のメッセージのtypoを修正 (thx @TheQuinbox!) ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 From 78af924a20792c81759cebd0d63ada2be20696cc Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 00:19:33 +0900 Subject: [PATCH 059/402] =?UTF-8?q?TimelineScheduler=E3=81=8CSystemResumeM?= =?UTF-8?q?ode=E3=81=8B=E3=82=89=E5=BE=A9=E5=B8=B0=E3=81=97=E3=81=AA?= =?UTF-8?q?=E3=81=84=E5=A0=B4=E5=90=88=E3=81=8C=E3=81=82=E3=82=8B=E4=B8=8D?= =?UTF-8?q?=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Timer のコールバックが dueTime で設定した時間よりも早く呼ばれる場合を考慮できていなかった Fixes: c8b60400 ("タイムラインの定期更新に使用するタイマーの間隔を動的に制御する") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/TimelineScheduler.cs | 8 ++------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index aa5692197..95e67efd1 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -17,6 +17,7 @@ * FIX: URL自動短縮の設定値が正しく表示されない不具合を修正 * FIX: 関連発言表示で一部のツイートの読み込みがエラーになると関連発言タブに何も表示されなくなる不具合を修正 * FIX: 英語版のメッセージのtypoを修正 (thx @TheQuinbox!) + * FIX: スリープからの復帰後に発言一覧の自動更新が停止する場合がある不具合を修正 ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 diff --git a/OpenTween/TimelineScheduler.cs b/OpenTween/TimelineScheduler.cs index 07648d814..51ebfd73a 100644 --- a/OpenTween/TimelineScheduler.cs +++ b/OpenTween/TimelineScheduler.cs @@ -230,12 +230,8 @@ private async Task TimerCallback_AfterSystemResume() // systemResumeMode では一定期間経過後に全てのタイムラインを更新する var now = DateTimeUtc.Now; - var nextScheduledUpdateAll = this.SystemResumedAt + this.UpdateAfterSystemResume; - if (nextScheduledUpdateAll - now < TimeSpan.Zero) - { - this.systemResumeMode = false; - await this.RunUpdateTasks(UpdateTask.All, now).ConfigureAwait(false); - } + this.systemResumeMode = false; + await this.RunUpdateTasks(UpdateTask.All, now).ConfigureAwait(false); } private async Task RunUpdateTasks(UpdateTask tasks, DateTimeUtc now) From c4e5bba27b456648bf5a29c02388d01c51536ef4 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 00:27:01 +0900 Subject: [PATCH 060/402] =?UTF-8?q?TimelineScheduler=E5=86=85=E3=81=A7?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8BTimer=E3=81=8C=E9=81=A9?= =?UTF-8?q?=E5=88=87=E3=81=AB=E7=A0=B4=E6=A3=84=E3=81=95=E3=82=8C=E3=81=AA?= =?UTF-8?q?=E3=81=84=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: c8b60400 ("タイムラインの定期更新に使用するタイマーの間隔を動的に制御する") --- OpenTween/TimelineScheduler.cs | 21 ++++++++++++++++++++- OpenTween/Tween.cs | 1 + 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/OpenTween/TimelineScheduler.cs b/OpenTween/TimelineScheduler.cs index 51ebfd73a..d25da195f 100644 --- a/OpenTween/TimelineScheduler.cs +++ b/OpenTween/TimelineScheduler.cs @@ -29,7 +29,7 @@ namespace OpenTween { - public class TimelineScheduler + public class TimelineScheduler : IDisposable { private readonly AsyncTimer timer; @@ -37,6 +37,8 @@ public class TimelineScheduler private bool systemResumeMode = false; private bool preventTimerUpdate = false; + public bool IsDisposed { get; private set; } = false; + public bool Enabled { get => this.enabled; @@ -360,5 +362,22 @@ private TimeSpan NextTimerDelay() return delay > TimeSpan.Zero ? delay : TimeSpan.Zero; } + + protected virtual void Dispose(bool disposing) + { + if (this.IsDisposed) + return; + + if (disposing) + this.timer.Dispose(); + + this.IsDisposed = true; + } + + public void Dispose() + { + this.Dispose(disposing: true); + GC.SuppressFinalize(this); + } } } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 52ad95cbf..23ecd0c2c 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -496,6 +496,7 @@ protected override void Dispose(bool disposing) //sf.Dispose(); sfTab.Dispose(); + this.timelineScheduler.Dispose(); this.workerCts.Cancel(); if (IconCache != null) From 6172722058e6509faf576f06281566859007d4d1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 00:52:46 +0900 Subject: [PATCH 061/402] =?UTF-8?q?TimelineScheduler=E3=81=AE=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=B3=E3=83=BC=E3=83=89=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TimelineScheduerTest.cs | 189 +++++++++++++++ OpenTween/TimelineScheduler.cs | 295 +++++++----------------- OpenTween/Tween.cs | 28 +-- 3 files changed, 283 insertions(+), 229 deletions(-) create mode 100644 OpenTween.Tests/TimelineScheduerTest.cs diff --git a/OpenTween.Tests/TimelineScheduerTest.cs b/OpenTween.Tests/TimelineScheduerTest.cs new file mode 100644 index 000000000..087f9ddff --- /dev/null +++ b/OpenTween.Tests/TimelineScheduerTest.cs @@ -0,0 +1,189 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace OpenTween +{ + public class TimelineScheduerTest + { + private class TestTimelineScheduler : TimelineScheduler + { + public MockTimer mockTimer = new MockTimer(() => Task.CompletedTask); + + public TestTimelineScheduler() + : base() + { + } + + protected override ITimer CreateTimer(Func callback) + => this.mockTimer = new MockTimer(callback); + } + + [Fact] + public async Task Callback_Test() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + using var scheduler = new TestTimelineScheduler(); + var mockTimer = scheduler.mockTimer; + + Assert.False(mockTimer.IsTimerRunning); + + var count = 0; + scheduler.UpdateFunc[TimelineSchedulerTaskType.Home] = () => + { + count++; + TestUtils.DriftTime(TimeSpan.FromSeconds(10)); + return Task.CompletedTask; + }; + scheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = TimeSpan.FromMinutes(1); + scheduler.Enabled = true; + + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.Zero, mockTimer.DueTime); + + // 0:00:00 - 0:00:10 + await mockTimer.Invoke(); + + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromSeconds(50), mockTimer.DueTime); // UpdateFunc 内で掛かった時間を減算する + } + } + + [Fact] + public async Task Callback_SystemResumeTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + using var scheduler = new TestTimelineScheduler(); + var mockTimer = scheduler.mockTimer; + + Assert.False(mockTimer.IsTimerRunning); + + var count = 0; + scheduler.UpdateFunc[TimelineSchedulerTaskType.Home] = () => + { + count++; + return Task.CompletedTask; + }; + scheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = TimeSpan.FromMinutes(1); + scheduler.UpdateAfterSystemResume = TimeSpan.FromMinutes(10); + scheduler.Enabled = true; + + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.Zero, mockTimer.DueTime); + + // 0:00:00 + await mockTimer.Invoke(); + + Assert.Equal(1, count); // invoked + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(1), mockTimer.DueTime); + + scheduler.SystemResumed(); + + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(10), mockTimer.DueTime); + + // 0:10:00 + TestUtils.DriftTime(TimeSpan.FromMinutes(10)); + await mockTimer.Invoke(); + + Assert.Equal(2, count); // invoked + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(1), mockTimer.DueTime); + } + } + + [Fact] + public void RefreshSchedule_Test() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + using var scheduler = new TestTimelineScheduler(); + var mockTimer = scheduler.mockTimer; + + scheduler.Enabled = true; + Assert.False(mockTimer.IsTimerRunning); + + scheduler.LastUpdatedAt[TimelineSchedulerTaskType.Home] = DateTimeUtc.Now; + scheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = TimeSpan.FromMinutes(1); + scheduler.RefreshSchedule(); + + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(1), mockTimer.DueTime); + } + } + + [Fact] + public void RefreshSchedule_EmptyTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + using var scheduler = new TestTimelineScheduler(); + var mockTimer = scheduler.mockTimer; + + scheduler.Enabled = true; + Assert.False(mockTimer.IsTimerRunning); + + scheduler.RefreshSchedule(); + Assert.False(mockTimer.IsTimerRunning); + } + } + + [Fact] + public void RefreshSchedule_MultipleTest() + { + using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) + { + using var scheduler = new TestTimelineScheduler(); + var mockTimer = scheduler.mockTimer; + + scheduler.Enabled = true; + Assert.False(mockTimer.IsTimerRunning); + + scheduler.LastUpdatedAt[TimelineSchedulerTaskType.Home] = DateTimeUtc.Now; + scheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = TimeSpan.FromMinutes(2); + scheduler.LastUpdatedAt[TimelineSchedulerTaskType.Mention] = DateTimeUtc.Now; + scheduler.UpdateInterval[TimelineSchedulerTaskType.Mention] = TimeSpan.FromMinutes(3); + scheduler.RefreshSchedule(); + + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(2), mockTimer.DueTime); + + scheduler.LastUpdatedAt[TimelineSchedulerTaskType.Home] = DateTimeUtc.Now; + scheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = TimeSpan.FromMinutes(2); + scheduler.LastUpdatedAt[TimelineSchedulerTaskType.Mention] = DateTimeUtc.Now - TimeSpan.FromMinutes(2); + scheduler.UpdateInterval[TimelineSchedulerTaskType.Mention] = TimeSpan.FromMinutes(3); + scheduler.RefreshSchedule(); + + Assert.True(mockTimer.IsTimerRunning); + Assert.Equal(TimeSpan.FromMinutes(1), mockTimer.DueTime); + } + } + } +} diff --git a/OpenTween/TimelineScheduler.cs b/OpenTween/TimelineScheduler.cs index d25da195f..fc8016906 100644 --- a/OpenTween/TimelineScheduler.cs +++ b/OpenTween/TimelineScheduler.cs @@ -31,7 +31,18 @@ namespace OpenTween { public class TimelineScheduler : IDisposable { - private readonly AsyncTimer timer; + private static readonly TimelineSchedulerTaskType[] AllTaskTypes = + { + TimelineSchedulerTaskType.Home, + TimelineSchedulerTaskType.Mention, + TimelineSchedulerTaskType.Dm, + TimelineSchedulerTaskType.PublicSearch, + TimelineSchedulerTaskType.User, + TimelineSchedulerTaskType.List, + TimelineSchedulerTaskType.Config, + }; + + private readonly ITimer timer; private bool enabled = false; private bool systemResumeMode = false; @@ -47,88 +58,45 @@ public bool Enabled if (this.enabled == value) return; - if (value) - { - var now = DateTimeUtc.Now; - this.LastUpdateHome = now; - this.LastUpdateMention = now; - this.LastUpdateDm = now; - this.LastUpdatePublicSearch = now; - this.LastUpdateUser = now; - this.LastUpdateList = now; - this.LastUpdateConfig = now; - } this.enabled = value; - this.RefreshSchedule(); + this.Reset(); } } - public DateTimeUtc LastUpdateHome { get; private set; } = DateTimeUtc.MinValue; - public DateTimeUtc LastUpdateMention { get; private set; } = DateTimeUtc.MinValue; - public DateTimeUtc LastUpdateDm { get; private set; } = DateTimeUtc.MinValue; - public DateTimeUtc LastUpdatePublicSearch { get; private set; } = DateTimeUtc.MinValue; - public DateTimeUtc LastUpdateUser { get; private set; } = DateTimeUtc.MinValue; - public DateTimeUtc LastUpdateList { get; private set; } = DateTimeUtc.MinValue; - public DateTimeUtc LastUpdateConfig { get; private set; } = DateTimeUtc.MinValue; public DateTimeUtc SystemResumedAt { get; private set; } = DateTimeUtc.MinValue; - - public TimeSpan UpdateIntervalHome { get; set; } = Timeout.InfiniteTimeSpan; - public TimeSpan UpdateIntervalMention { get; set; } = Timeout.InfiniteTimeSpan; - public TimeSpan UpdateIntervalDm { get; set; } = Timeout.InfiniteTimeSpan; - public TimeSpan UpdateIntervalPublicSearch { get; set; } = Timeout.InfiniteTimeSpan; - public TimeSpan UpdateIntervalUser { get; set; } = Timeout.InfiniteTimeSpan; - public TimeSpan UpdateIntervalList { get; set; } = Timeout.InfiniteTimeSpan; - public TimeSpan UpdateIntervalConfig { get; set; } = Timeout.InfiniteTimeSpan; public TimeSpan UpdateAfterSystemResume { get; set; } = Timeout.InfiniteTimeSpan; - public bool EnableUpdateHome - => this.UpdateIntervalHome != Timeout.InfiniteTimeSpan; - - public bool EnableUpdateMention - => this.UpdateIntervalMention != Timeout.InfiniteTimeSpan; - - public bool EnableUpdateDm - => this.UpdateIntervalDm != Timeout.InfiniteTimeSpan; - - public bool EnableUpdatePublicSearch - => this.UpdateIntervalPublicSearch != Timeout.InfiniteTimeSpan; - - public bool EnableUpdateUser - => this.UpdateIntervalUser != Timeout.InfiniteTimeSpan; + public bool EnableUpdateSystemResume + => this.UpdateAfterSystemResume != Timeout.InfiniteTimeSpan; - public bool EnableUpdateList - => this.UpdateIntervalList != Timeout.InfiniteTimeSpan; + public Dictionary LastUpdatedAt { get; } + = new Dictionary(); - public bool EnableUpdateConfig - => this.UpdateIntervalConfig != Timeout.InfiniteTimeSpan; + public Dictionary UpdateInterval { get; } + = new Dictionary(); - public bool EnableUpdateSystemResume - => this.UpdateAfterSystemResume != Timeout.InfiniteTimeSpan; + public Dictionary> UpdateFunc { get; } + = new Dictionary>(); - public Func? UpdateHome; - public Func? UpdateMention; - public Func? UpdateDm; - public Func? UpdatePublicSearch; - public Func? UpdateUser; - public Func? UpdateList; - public Func? UpdateConfig; + public IEnumerable EnabledTaskTypes + => TimelineScheduler.AllTaskTypes.Where(x => this.IsEnabledType(x)); - [Flags] - private enum UpdateTask + public TimelineScheduler() { - None = 0, - Home = 1, - Mention = 1 << 2, - Dm = 1 << 3, - PublicSearch = 1 << 4, - User = 1 << 5, - List = 1 << 6, - Config = 1 << 7, - All = Home | Mention | Dm | PublicSearch | User | List | Config, + this.timer = this.CreateTimer(this.TimerCallback); + + foreach (var taskType in TimelineScheduler.AllTaskTypes) + { + this.LastUpdatedAt[taskType] = DateTimeUtc.MinValue; + this.UpdateInterval[taskType] = Timeout.InfiniteTimeSpan; + } } - public TimelineScheduler() - => this.timer = new AsyncTimer(this.TimerCallback); + protected virtual ITimer CreateTimer(Func callback) + => new AsyncTimer(callback); + + public bool IsEnabledType(TimelineSchedulerTaskType task) + => this.UpdateInterval[task] != Timeout.InfiniteTimeSpan; public void RefreshSchedule() { @@ -151,6 +119,15 @@ public void SystemResumed() this.RefreshSchedule(); } + public void Reset() + { + foreach (var taskType in TimelineScheduler.AllTaskTypes) + this.LastUpdatedAt[taskType] = DateTimeUtc.MinValue; + + this.systemResumeMode = false; + this.RefreshSchedule(); + } + private async Task TimerCallback() { try @@ -173,55 +150,13 @@ private async Task TimerCallback_Normal() { var now = DateTimeUtc.Now; var round = TimeSpan.FromSeconds(1); // 1秒未満の差異であればまとめて実行する - var tasks = UpdateTask.None; - - if (this.EnableUpdateHome) - { - var nextScheduledHome = this.LastUpdateHome + this.UpdateIntervalHome; - if (nextScheduledHome - now < round) - tasks |= UpdateTask.Home; - } - - if (this.EnableUpdateMention) - { - var nextScheduledMention = this.LastUpdateMention + this.UpdateIntervalMention; - if (nextScheduledMention - now < round) - tasks |= UpdateTask.Mention; - } - - if (this.EnableUpdateDm) - { - var nextScheduledDm = this.LastUpdateDm + this.UpdateIntervalDm; - if (nextScheduledDm - now < round) - tasks |= UpdateTask.Dm; - } - - if (this.EnableUpdatePublicSearch) - { - var nextScheduledPublicSearch = this.LastUpdatePublicSearch + this.UpdateIntervalPublicSearch; - if (nextScheduledPublicSearch - now < round) - tasks |= UpdateTask.PublicSearch; - } - - if (this.EnableUpdateUser) - { - var nextScheduledUser = this.LastUpdateUser + this.UpdateIntervalUser; - if (nextScheduledUser - now < round) - tasks |= UpdateTask.User; - } - - if (this.EnableUpdateList) - { - var nextScheduledList = this.LastUpdateList + this.UpdateIntervalList; - if (nextScheduledList - now < round) - tasks |= UpdateTask.List; - } + var tasks = new List(capacity: TimelineScheduler.AllTaskTypes.Length); - if (this.EnableUpdateConfig) + foreach (var taskType in this.EnabledTaskTypes) { - var nextScheduledConfig = this.LastUpdateConfig + this.UpdateIntervalConfig; - if (nextScheduledConfig - now < round) - tasks |= UpdateTask.Config; + var nextScheduledAt = this.LastUpdatedAt[taskType] + this.UpdateInterval[taskType]; + if (nextScheduledAt - now < round) + tasks.Add(taskType); } await this.RunUpdateTasks(tasks, now).ConfigureAwait(false); @@ -233,60 +168,18 @@ private async Task TimerCallback_AfterSystemResume() var now = DateTimeUtc.Now; this.systemResumeMode = false; - await this.RunUpdateTasks(UpdateTask.All, now).ConfigureAwait(false); + await this.RunUpdateTasks(TimelineScheduler.AllTaskTypes, now).ConfigureAwait(false); } - private async Task RunUpdateTasks(UpdateTask tasks, DateTimeUtc now) + private async Task RunUpdateTasks(IEnumerable taskTypes, DateTimeUtc now) { - var updateTasks = new List>(capacity: 7); + var updateTasks = new List>(capacity: TimelineScheduler.AllTaskTypes.Length); - if ((tasks & UpdateTask.Home) == UpdateTask.Home) + foreach (var taskType in taskTypes) { - this.LastUpdateHome = now; - if (this.UpdateHome != null) - updateTasks.Add(this.UpdateHome); - } - - if ((tasks & UpdateTask.Mention) == UpdateTask.Mention) - { - this.LastUpdateMention = now; - if (this.UpdateMention != null) - updateTasks.Add(this.UpdateMention); - } - - if ((tasks & UpdateTask.Dm) == UpdateTask.Dm) - { - this.LastUpdateDm = now; - if (this.UpdateDm != null) - updateTasks.Add(this.UpdateDm); - } - - if ((tasks & UpdateTask.PublicSearch) == UpdateTask.PublicSearch) - { - this.LastUpdatePublicSearch = now; - if (this.UpdatePublicSearch != null) - updateTasks.Add(this.UpdatePublicSearch); - } - - if ((tasks & UpdateTask.User) == UpdateTask.User) - { - this.LastUpdateUser = now; - if (this.UpdateUser != null) - updateTasks.Add(this.UpdateUser); - } - - if ((tasks & UpdateTask.List) == UpdateTask.List) - { - this.LastUpdateList = now; - if (this.UpdateList != null) - updateTasks.Add(this.UpdateList); - } - - if ((tasks & UpdateTask.Config) == UpdateTask.Config) - { - this.LastUpdateConfig = now; - if (this.UpdateConfig != null) - updateTasks.Add(this.UpdateConfig); + this.LastUpdatedAt[taskType] = now; + if (this.UpdateFunc.TryGetValue(taskType, out var func)) + updateTasks.Add(func); } await Task.WhenAll(updateTasks.Select(x => Task.Run(x))) @@ -302,64 +195,25 @@ private TimeSpan NextTimerDelay() // systemResumeMode が有効な間は UpdateAfterSystemResume 以外の設定値を見ない var nextScheduledUpdateAll = this.SystemResumedAt + this.UpdateAfterSystemResume; delay = nextScheduledUpdateAll - DateTimeUtc.Now; - - return delay > TimeSpan.Zero ? delay : TimeSpan.Zero; } - - // 次に更新が予定される時刻を判定する - var min = DateTimeUtc.MaxValue; - - if (this.EnableUpdateHome) - { - var nextScheduledHome = this.LastUpdateHome + this.UpdateIntervalHome; - if (nextScheduledHome < min) - min = nextScheduledHome; - } - - if (this.EnableUpdateMention) - { - var nextScheduledMention = this.LastUpdateMention + this.UpdateIntervalMention; - if (nextScheduledMention < min) - min = nextScheduledMention; - } - - if (this.EnableUpdateDm) - { - var nextScheduledDm = this.LastUpdateDm + this.UpdateIntervalDm; - if (nextScheduledDm < min) - min = nextScheduledDm; - } - - if (this.EnableUpdatePublicSearch) + else { - var nextScheduledPublicSearch = this.LastUpdatePublicSearch + this.UpdateIntervalPublicSearch; - if (nextScheduledPublicSearch < min) - min = nextScheduledPublicSearch; - } + // 次に更新が予定される時刻を判定する + var min = DateTimeUtc.MaxValue; - if (this.EnableUpdateUser) - { - var nextScheduledUser = this.LastUpdateUser + this.UpdateIntervalUser; - if (nextScheduledUser < min) - min = nextScheduledUser; - } + foreach (var taskType in this.EnabledTaskTypes) + { + var nextScheduledAt = this.LastUpdatedAt[taskType] + this.UpdateInterval[taskType]; + if (nextScheduledAt < min) + min = nextScheduledAt; + } - if (this.EnableUpdateList) - { - var nextScheduledList = this.LastUpdateList + this.UpdateIntervalList; - if (nextScheduledList < min) - min = nextScheduledList; - } + if (min == DateTimeUtc.MaxValue) + return Timeout.InfiniteTimeSpan; - if (this.EnableUpdateConfig) - { - var nextScheduledConfig = this.LastUpdateConfig + this.UpdateIntervalConfig; - if (nextScheduledConfig < min) - min = nextScheduledConfig; + delay = min - DateTimeUtc.Now; } - delay = min - DateTimeUtc.Now; - return delay > TimeSpan.Zero ? delay : TimeSpan.Zero; } @@ -380,4 +234,15 @@ public void Dispose() GC.SuppressFinalize(this); } } + + public enum TimelineSchedulerTaskType + { + Home, + Mention, + Dm, + PublicSearch, + User, + List, + Config, + } } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 23ecd0c2c..726366f85 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1177,13 +1177,13 @@ private void TweenMain_Load(object sender, EventArgs e) //タイマー設定 - this.timelineScheduler.UpdateHome = () => this.InvokeAsync(() => this.RefreshTabAsync()); - this.timelineScheduler.UpdateMention = () => this.InvokeAsync(() => this.RefreshTabAsync()); - this.timelineScheduler.UpdateDm = () => this.InvokeAsync(() => this.RefreshTabAsync()); - this.timelineScheduler.UpdatePublicSearch = () => this.InvokeAsync(() => this.RefreshTabAsync()); - this.timelineScheduler.UpdateUser = () => this.InvokeAsync(() => this.RefreshTabAsync()); - this.timelineScheduler.UpdateList = () => this.InvokeAsync(() => this.RefreshTabAsync()); - this.timelineScheduler.UpdateConfig = () => this.InvokeAsync(() => Task.WhenAll(new[] + this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Home] = () => this.InvokeAsync(() => this.RefreshTabAsync()); + this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Mention] = () => this.InvokeAsync(() => this.RefreshTabAsync()); + this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Dm] = () => this.InvokeAsync(() => this.RefreshTabAsync()); + this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.PublicSearch] = () => this.InvokeAsync(() => this.RefreshTabAsync()); + this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.User] = () => this.InvokeAsync(() => this.RefreshTabAsync()); + this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.List] = () => this.InvokeAsync(() => this.RefreshTabAsync()); + this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Config] = () => this.InvokeAsync(() => Task.WhenAll(new[] { this.doGetFollowersMenu(), this.RefreshBlockIdsAsync(), @@ -1354,13 +1354,13 @@ private void RefreshTimelineScheduler() static TimeSpan intervalSecondsOrDisabled(int seconds) => seconds == 0 ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(seconds); - this.timelineScheduler.UpdateIntervalHome = intervalSecondsOrDisabled(SettingManager.Common.TimelinePeriod); - this.timelineScheduler.UpdateIntervalMention = intervalSecondsOrDisabled(SettingManager.Common.ReplyPeriod); - this.timelineScheduler.UpdateIntervalDm = intervalSecondsOrDisabled(SettingManager.Common.DMPeriod); - this.timelineScheduler.UpdateIntervalPublicSearch = intervalSecondsOrDisabled(SettingManager.Common.PubSearchPeriod); - this.timelineScheduler.UpdateIntervalUser = intervalSecondsOrDisabled(SettingManager.Common.UserTimelinePeriod); - this.timelineScheduler.UpdateIntervalList = intervalSecondsOrDisabled(SettingManager.Common.ListsPeriod); - this.timelineScheduler.UpdateIntervalConfig = TimeSpan.FromHours(6); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = intervalSecondsOrDisabled(SettingManager.Common.TimelinePeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Mention] = intervalSecondsOrDisabled(SettingManager.Common.ReplyPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Dm] = intervalSecondsOrDisabled(SettingManager.Common.DMPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.PublicSearch] = intervalSecondsOrDisabled(SettingManager.Common.PubSearchPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.User] = intervalSecondsOrDisabled(SettingManager.Common.UserTimelinePeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.List] = intervalSecondsOrDisabled(SettingManager.Common.ListsPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Config] = TimeSpan.FromHours(6); this.timelineScheduler.UpdateAfterSystemResume = TimeSpan.FromSeconds(30); this.timelineScheduler.RefreshSchedule(); From 1cb3f854c8d05d2c25c8f82dfb7064fb4470e64a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 01:16:09 +0900 Subject: [PATCH 062/402] =?UTF-8?q?=E3=82=B7=E3=82=B9=E3=83=86=E3=83=A0?= =?UTF-8?q?=E3=81=AE=E6=97=A5=E6=99=82=E3=81=8C=E5=A4=89=E6=9B=B4=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AFTimelineScheduler?= =?UTF-8?q?=E3=81=AE=E7=8A=B6=E6=85=8B=E3=82=92=E3=83=AA=E3=82=BB=E3=83=83?= =?UTF-8?q?=E3=83=88=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 日時が過去の方向に変更された場合、次回の更新時刻が設定された間隔以上に後の時刻にスケジュールされてしまうため Fixes: c8b60400 ("タイムラインの定期更新に使用するタイマーの間隔を動的に制御する") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 2 ++ 2 files changed, 3 insertions(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 95e67efd1..c68dd363e 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -18,6 +18,7 @@ * FIX: 関連発言表示で一部のツイートの読み込みがエラーになると関連発言タブに何も表示されなくなる不具合を修正 * FIX: 英語版のメッセージのtypoを修正 (thx @TheQuinbox!) * FIX: スリープからの復帰後に発言一覧の自動更新が停止する場合がある不具合を修正 + * FIX: システムの日時を変更すると発言一覧の更新間隔が正しく計算されない場合がある不具合を修正 ==== Ver 2.4.3(2019/12/06) * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 726366f85..3b1e8e7e0 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -10991,6 +10991,8 @@ private void SystemEvents_TimeChanged(object sender, EventArgs e) this.DispSelectedPost(forceupdate: true); } + + this.timelineScheduler.Reset(); } private void TimelineRefreshEnableChange(bool isEnable) From 18e07552545fa9aeb197f92d5935d8f563265dff Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 02:17:13 +0900 Subject: [PATCH 063/402] =?UTF-8?q?develop=E3=83=96=E3=83=A9=E3=83=B3?= =?UTF-8?q?=E3=83=81=E3=81=A7=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8BAssemblyP?= =?UTF-8?q?roduct=E3=81=AE=E5=80=A4=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit APIキーの暗号化パスワードも変更されるため改めて設定し直す --- OpenTween/ApplicationSettings.cs | 24 ++++++++++++------------ OpenTween/Properties/AssemblyInfo.cs | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/OpenTween/ApplicationSettings.cs b/OpenTween/ApplicationSettings.cs index 2ce610626..d2ad11c79 100644 --- a/OpenTween/ApplicationSettings.cs +++ b/OpenTween/ApplicationSettings.cs @@ -120,12 +120,12 @@ internal static class ApplicationSettings /// /// Twitter API Key /// - public static readonly ApiKey TwitterConsumerKey = ApiKey.Create("%e%lhBzdIOsT0NwiaraGF6M8Q==%DtKV/SIVVVGA0tnaubpG0c5VL52DtkndCd5bYNPfQ/M=%4pkaNg/LhtyFPUlhMG9v+2DWuYxlYZSB9md5J/azJbA="); + public static readonly ApiKey TwitterConsumerKey = ApiKey.Create("%e%EGv00cec1j05bMzbfAnsug==%ApO4PjZvnhixxFDqNh5qeqUTyAIEhoDvhhTaspVVjoA=%48Wxazf5JpDdIbkG0I8nme6/weUdEmZMRqfXAmCNr+Y="); /// /// Twitter API Key Secret /// - public static readonly ApiKey TwitterConsumerSecret = ApiKey.Create("%e%qYUFwFZCk/oYRwkF+d5G1A==%wqJcbfvhm3avxQaFha6hjLZkuo07y0EOUzOfT66NyuR4KOe5V3Jgvw6Kvy5V/VKafZHmq8j6xyKzytQQa7kpUw==%VgfPeI7XK/zhds2Tk/QTo5hPe2/4rRsGnLascX5Lp1I="); + public static readonly ApiKey TwitterConsumerSecret = ApiKey.Create("%e%p93BdDzlwbYIC5Ych/47OQ==%xYZTCYaBxzS4An3o7Qcigjp9QMtu5vi5iEAW/sNgoOoAUyuHJRPP3Ovs20ZV2fAYKxUDiu76dxLfObwI7QjSRA==%YEruRDAQdbJzO+y6kn7+U/uIyIyNra/8Ulo+L6KJcWA="); //===================================================================== // Foursquare @@ -134,12 +134,12 @@ internal static class ApplicationSettings /// /// Foursquare Client Id /// - public static readonly ApiKey FoursquareClientId = ApiKey.Create("%e%PUhzXizCMlOCLv6AjDEwWw==%p6wCukrAWVmPv+mevyhIBJsTmld+nN8jqqdcrUM2bnqvVU9+W1V9rtMrM19Ew2A2Uw2N7yPAmymR6YgVxO5hZw==%PcIbp7rt0Bom/igLAbOR5TwIfdF7Ucej4+tCQuZ7ALE="); + public static readonly ApiKey FoursquareClientId = ApiKey.Create("%e%zNX0U6Eul2bdpkzQgcd/WA==%koGoTYoVLvQ6T5bsnI+dJjJ+REMnlJIhTnibhI6MagmHPA5hzY6DQom+PpQxBZX2CS2fZW1Ac82HzTzb3J7gNw==%qOMdPQ3UN7IWT4jJegYQnRxorZm/zaEt7/n6fd1eFcM="); /// /// Foursquare Client Secret /// - public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("%e%MfvV15MhI4znNalkQLKGUA==%ONIAN5e6ZUeCeAqFl6rkDIZWvKT9xEUA7S2c6H5KVs6Ba8p0fzxKnH+ay1x/awpjtTRtfkY7d8dOwouxEJJviQ==%WvG6oTGYIvUpKGyofIdAcP5jVTC7oLuK8KB7aT4U9vA="); + public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("%e%3Zw+G9P32WgIi1ooBeDSCg==%coygRxFBSrxMW5o4dkD64ftx0C7axFkJlceb52XqDaiQKkf8q0Szavcw+t3MsxFQTkwL3ob7mehmCSdSpJPLTA==%XTrAyfrDBzdeKGPIXTD2JFU65uZqh8fs9tyf+fLaJeY="); //===================================================================== // bit.ly @@ -148,12 +148,12 @@ internal static class ApplicationSettings /// /// bit.ly Client ID /// - public static readonly ApiKey BitlyClientId = ApiKey.Create("%e%D6d+cV9roc9oRyFHlzzpNA==%5PU2keurc+lfK56rsbEftpHz9S/X4xVg8vRKLXHksspOtOeLXHlR55XdPX4vafIr%X5bBNiqWcqeIThNZmDkz3rM2ObtIYPqVV5ijCg4rlME="); + public static readonly ApiKey BitlyClientId = ApiKey.Create("%e%VtBYaO301PMy/eesjAJwuQ==%wK9fwaXlaq2wOCbJqzfwUzf4h+xAUJ445+wjI6uT3ANyag2LPJBYpfCQ3V+qnNlR%kmyyVMp8JPubACjFEd1zZMV2bddMimSj86e/ONegTeI="); /// /// bit.ly Client Secret /// - public static readonly ApiKey BitlyClientSecret = ApiKey.Create("%e%p3whdM7O13e3Wos1EBCgZg==%uaZQscha5IYHVIwedXo4klPBMxzyFmJwB4cO3+hzTVm7KGhnxsHh44aoLfLTzuzI%mqFsvWt7k7ps2HcCjxwbZS66lGcFHae1rG6XWjxMqfY="); + public static readonly ApiKey BitlyClientSecret = ApiKey.Create("%e%jvdQqgh0Aj4e8HANczWELA==%FHevK6YJ/5L083pCJnUQ65bfz+sbwLZw4hUXIOw9PXRa8YnmVZ2KMwuHRRbdZUZl%1f/0LoSAuC0wyfKMhiohXNPGWY7wyQbqr2XVyKtjpFk="); //===================================================================== // TINAMI @@ -162,7 +162,7 @@ internal static class ApplicationSettings /// /// TINAMI APIキー /// - public static readonly ApiKey TINAMIApiKey = ApiKey.Create("%e%7hQ5WcIjLOahw9VNyIU4qA==%z/T24upQAfNub0WiMrxLjg==%Mh+7SC+8SR514jm8tSgrRqn70i+psuox5dyQ5cHh7zs="); + public static readonly ApiKey TINAMIApiKey = ApiKey.Create("%e%OA+C4u5v/9Oc2xIOEKt6Ng==%xLrMgeXaYSIaW5LYEA2viA==%/0bWO/UMCYH2BRxPKvi7JCW/CXxp/JmincpFNRlvhOQ="); //===================================================================== // Microsoft Translator API (Cognitive Service) @@ -171,7 +171,7 @@ internal static class ApplicationSettings /// /// Translator Text API Subscription Key /// - public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("%e%OftqWcavvEFL3ecdcE80KQ==%B/u2U2A84zfhHPV2MARqDTD0YPFruSgdOdP1+JqRaAAg5gEpTjCQfzr7noDN8YCa%73W3WtAt4e9G4HRou2Zu9s/D5cIQ8ccxDsv60KnLvWA="); + public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("%e%ysNsopqjk7fEikJNfX3ZtQ==%ZS4Gzq9PSUzBGKabQWi5To2nVLl8R3D+i/7nj5dACFAkBvQkxmrgJCnvON9cdF/+%1bayEnkpd4gbcyTTwB9PILWdku3YS52FuHskkpIhlXQ="); //===================================================================== // Imgur @@ -180,12 +180,12 @@ internal static class ApplicationSettings /// /// Imgur Client ID /// - public static readonly ApiKey ImgurClientId = ApiKey.Create("%e%+ncaqKgmWPsHj8vm9vuR0A==%sw2Vvu3QQAFqqUU9FTGeRQ==%3cJIVrvCot+8LU4/l9iYQtsjn3dUYOdere56VsQIpNU="); + public static readonly ApiKey ImgurClientId = ApiKey.Create("%e%YQirOk0lRw8zjhrTPlyRrQ==%ysNbeo//DruosSIzXquwiw==%126uNNTZshuw/SW9hd1ME/KCMpKSfjeboSRtQRfVQwc="); /// /// Imgur Client Secret /// - public static readonly ApiKey ImgurClientSecret = ApiKey.Create("%e%p3wLXhBzIpGOBpYn0w5G4w==%y0UO+MKvGnebqWJd6nKLifBYecFc9i4Bdf6n5+SuDEoGFSaDF54zCeRvJ8pVk9DF%LY6jZ/duMjRprZSR0qiIj/dentKm7AtLMjQq17mdlCg="); + public static readonly ApiKey ImgurClientSecret = ApiKey.Create("%e%+IHTR8uXh2Mig6zGkawjeA==%vYQDZ+Tw5Rol4mQRC/yzXywuaNPWgoL5kLIg5VdUiCnSX5EPGQC5+QUkTzGz/fqv%+mOv8ekXLoZKe05yyXJ8Sx0cjuimoPQA30k/571wVRw="); //===================================================================== // Mobypicture @@ -194,7 +194,7 @@ internal static class ApplicationSettings /// /// Mobypicture Developer Key /// - public static readonly ApiKey MobypictureKey = ApiKey.Create("%e%gQlFICkgKMP5bZ15DfOFzQ==%n+3Dfxy4IMtFNljJgdDLuoh1MdzLAk6/ZsKdGugy3BA=%yuM7lNI8qFWYj6ppDdM2bC9EtHO+ms1G6vl9xTjijek="); + public static readonly ApiKey MobypictureKey = ApiKey.Create("%e%1FQ6vgxHCduEDyyJ7UK1ug==%xNBXVlAgJ8XiXZ1LSgGvEL1Vk1m4EzQ+6T/yigTgRHw=%xCAlJ1gBpe8G1Us6wXZBkYGxccFvRyRhmnFM4ocuhHQ="); //===================================================================== // Tumblr @@ -203,6 +203,6 @@ internal static class ApplicationSettings /// /// Tumblr OAuth Consumer Key /// - public static readonly ApiKey TumblrConsumerKey = ApiKey.Create("%e%WJZTGDwe4njFpgKGQi5jRg==%gY2QO1so6QOfWitwxYP8XbIp98AtN3tDtoK4Q6bUOePkXVlhr4uE/VxhMg56Nblxt34Zy/8hpQSi0hlhuS2drQ==%hGKO3RVp0WaT3coVbo3H65r2pmKB8TTuiIbBzAzaV1A="); + public static readonly ApiKey TumblrConsumerKey = ApiKey.Create("%e%1jQuOn2+l8O9i0/ld/VV5Q==%SiBRxJWj4Cbq/btPs63Rr2xOyw4XgTlV+lVkHkvIapBRkUaqGJxV7R/j5ljX+QW0ruBXNy+cpZFeEZFfB2jvSQ==%3GdYHow0pAlPQRY/wquX1AaxjzSabStRj8zbTXct1S4="); } } diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 3eeb21e18..0a9786de8 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -5,11 +5,11 @@ // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 // アセンブリに関連付けられている情報を変更するには、 // これらの属性値を変更してください。 -[assembly: AssemblyTitle("OpenTween")] +[assembly: AssemblyTitle("OpenTween (dev)")] [assembly: AssemblyDescription("Client of Twitter. Free software(GPLv3)")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("OpenTween")] +[assembly: AssemblyProduct("OpenTween (dev)")] [assembly: AssemblyCopyright("(C) 2011 OpenTween contributors")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] From 96b083c786c80ae55928b747fb7ec563199d3eb8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 02:51:44 +0900 Subject: [PATCH 064/402] =?UTF-8?q?API=E3=82=AD=E3=83=BC=E3=81=AE=E5=BE=A9?= =?UTF-8?q?=E5=8F=B7=E3=81=AB=E5=A4=B1=E6=95=97=E3=81=97=E3=81=9F=E5=A0=B4?= =?UTF-8?q?=E5=90=88=E3=81=AE=E3=82=A8=E3=83=A9=E3=83=BC=E3=83=A1=E3=83=83?= =?UTF-8?q?=E3=82=BB=E3=83=BC=E3=82=B8=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 12 ++++++++++++ OpenTween/Properties/Resources.Designer.cs | 12 ++++++++++++ OpenTween/Properties/Resources.en.resx | 4 ++++ OpenTween/Properties/Resources.resx | 4 ++++ 4 files changed, 32 insertions(+) diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 3f2f6802b..3d6d619c7 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -63,6 +63,7 @@ internal class MyApplication [STAThread] static int Main(string[] args) { + WarnIfApiKeyError(); WarnIfRunAsAdministrator(); if (!CheckRuntimeVersion()) @@ -114,6 +115,17 @@ static int Main(string[] args) return 0; } + private static void WarnIfApiKeyError() + { + var canDecrypt = ApplicationSettings.TwitterConsumerKey.TryGetValue(out _); + if (!canDecrypt) + { + var message = Properties.Resources.WarnIfApiKeyError_Message; + MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning); + Environment.Exit(-1); + } + } + /// /// OpenTween が管理者権限で実行されている場合に警告を表示します /// diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 298e6f129..885fe2fcb 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -3185,6 +3185,18 @@ internal static string VimeoInfoText6 { } } + /// + /// API キーの取得に失敗しました。 + /// + ///OpenTween の製品名を変更して使用する場合は、新たに API キーを取得して ApplicationSetting.cs に設定し直してください。 + ///少なくとも Twitter API のキーが正しく設定されていれば、起動できる状態になります。 に類似しているローカライズされた文字列を検索します。 + /// + internal static string WarnIfApiKeyError_Message { + get { + return ResourceManager.GetString("WarnIfApiKeyError_Message", resourceCulture); + } + } + /// /// {0}を管理者権限で実行する事は推奨されません。 /// diff --git a/OpenTween/Properties/Resources.en.resx b/OpenTween/Properties/Resources.en.resx index c955aab6e..1962bb230 100644 --- a/OpenTween/Properties/Resources.en.resx +++ b/OpenTween/Properties/Resources.en.resx @@ -347,6 +347,10 @@ Do you retry to update status? Views: Comments: Length: + Failed to retrieve the API key. + +If you change the product name of OpenTween, you must apply for a new API key and modify the ApplicationSettings. +At least if the Twitter API key has been changed correctly, you can launch the application. It is not recommended to run {0} as administrator. * {0} does not require administrator privileges. diff --git a/OpenTween/Properties/Resources.resx b/OpenTween/Properties/Resources.resx index 5e2a744da..dfc9c8587 100644 --- a/OpenTween/Properties/Resources.resx +++ b/OpenTween/Properties/Resources.resx @@ -367,6 +367,10 @@ 再生数: コメント数: 再生時間: + API キーの取得に失敗しました。 + +OpenTween の製品名を変更して使用する場合は、新たに API キーを取得して ApplicationSetting.cs に設定し直してください。 +少なくとも Twitter API のキーが正しく設定されていれば、起動できる状態になります。 {0}を管理者権限で実行する事は推奨されません。 * {0}は管理者権限を必要とするソフトウェアではありません。 From d9b8a02e8c994ad6cd201c218fca24a8ce6dbcb0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 2 Feb 2022 02:11:28 +0900 Subject: [PATCH 065/402] =?UTF-8?q?ApplicationSettings=E3=81=AB=E3=83=AA?= =?UTF-8?q?=E3=83=AA=E3=83=BC=E3=82=B9=E7=94=A8=E3=81=AEAPI=E3=82=AD?= =?UTF-8?q?=E3=83=BC=E3=82=92=E3=82=BB=E3=83=83=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationSettings.cs | 24 ++++++++++++------------ OpenTween/Properties/AssemblyInfo.cs | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/OpenTween/ApplicationSettings.cs b/OpenTween/ApplicationSettings.cs index d2ad11c79..898d25cc9 100644 --- a/OpenTween/ApplicationSettings.cs +++ b/OpenTween/ApplicationSettings.cs @@ -120,12 +120,12 @@ internal static class ApplicationSettings /// /// Twitter API Key /// - public static readonly ApiKey TwitterConsumerKey = ApiKey.Create("%e%EGv00cec1j05bMzbfAnsug==%ApO4PjZvnhixxFDqNh5qeqUTyAIEhoDvhhTaspVVjoA=%48Wxazf5JpDdIbkG0I8nme6/weUdEmZMRqfXAmCNr+Y="); + public static readonly ApiKey TwitterConsumerKey = ApiKey.Create("%e%qDp/VaX9FqN86TBznspjyg==%idrCd4S0jPTfFNhqTc21XT/vADksqLIj9x7MO13O2sQ=%/Zf9x95CNa6cQTXUYcrqR+poU31lZysqmdEqorhruWo="); /// /// Twitter API Key Secret /// - public static readonly ApiKey TwitterConsumerSecret = ApiKey.Create("%e%p93BdDzlwbYIC5Ych/47OQ==%xYZTCYaBxzS4An3o7Qcigjp9QMtu5vi5iEAW/sNgoOoAUyuHJRPP3Ovs20ZV2fAYKxUDiu76dxLfObwI7QjSRA==%YEruRDAQdbJzO+y6kn7+U/uIyIyNra/8Ulo+L6KJcWA="); + public static readonly ApiKey TwitterConsumerSecret = ApiKey.Create("%e%ocBkKu4aZI5PsbboE7+Ajg==%4IlCFjqusmFPQHbcDutms/1bTOSwgxd3ah1NPCj23WUu66nGjUb5oAEMiNSv41Pb6n5utbFQrgqwJRdl3jVnfQ==%jpx+NlcN1w8UQ8kda1LgyHEmiVwl/PLGCVPotrp6pd8="); //===================================================================== // Foursquare @@ -134,12 +134,12 @@ internal static class ApplicationSettings /// /// Foursquare Client Id /// - public static readonly ApiKey FoursquareClientId = ApiKey.Create("%e%zNX0U6Eul2bdpkzQgcd/WA==%koGoTYoVLvQ6T5bsnI+dJjJ+REMnlJIhTnibhI6MagmHPA5hzY6DQom+PpQxBZX2CS2fZW1Ac82HzTzb3J7gNw==%qOMdPQ3UN7IWT4jJegYQnRxorZm/zaEt7/n6fd1eFcM="); + public static readonly ApiKey FoursquareClientId = ApiKey.Create("%e%KyanhtUu0qXIU2AnLkvPnQ==%S/xBHNqFOxoxzvm78ELIxihdzq+Hu7iXboWQEIPztc928zVY/jJ50Qyc/ic/twGzBkdz/Mz+63wfoU/u7jDg4A==%zJDIOdYGgbQ5gJNvBqGl1ETVok7IJrBB/nXxvcUCuPA="); /// /// Foursquare Client Secret /// - public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("%e%3Zw+G9P32WgIi1ooBeDSCg==%coygRxFBSrxMW5o4dkD64ftx0C7axFkJlceb52XqDaiQKkf8q0Szavcw+t3MsxFQTkwL3ob7mehmCSdSpJPLTA==%XTrAyfrDBzdeKGPIXTD2JFU65uZqh8fs9tyf+fLaJeY="); + public static readonly ApiKey FoursquareClientSecret = ApiKey.Create("%e%YZeT/G9cZ0Lub68LFU15bw==%x9LQxogt6ejhWOAV1toXn0zeDeBpV0lMEmJGRCpsIrizJNl3kDcDKWGu1CYSOXgk2hAoqm5IOBq4RAExE0Z2Qw==%yMdCK6WJo7WmvAYBIJ+qZrxAKVIPOR3nftfoXzyzlgY="); //===================================================================== // bit.ly @@ -148,12 +148,12 @@ internal static class ApplicationSettings /// /// bit.ly Client ID /// - public static readonly ApiKey BitlyClientId = ApiKey.Create("%e%VtBYaO301PMy/eesjAJwuQ==%wK9fwaXlaq2wOCbJqzfwUzf4h+xAUJ445+wjI6uT3ANyag2LPJBYpfCQ3V+qnNlR%kmyyVMp8JPubACjFEd1zZMV2bddMimSj86e/ONegTeI="); + public static readonly ApiKey BitlyClientId = ApiKey.Create("%e%Yg3QHOAzEo189O5ujHbizA==%CnzHsBl4mUTFf2wJr9cRYd2OzDnnlLux48xhWT0hdkDz+XgGeiBCqZ/L17rGze4r%VCZDb+LcYtPviR0H1QYnRDMugrhL9MXicw3yt2jKAPA="); /// /// bit.ly Client Secret /// - public static readonly ApiKey BitlyClientSecret = ApiKey.Create("%e%jvdQqgh0Aj4e8HANczWELA==%FHevK6YJ/5L083pCJnUQ65bfz+sbwLZw4hUXIOw9PXRa8YnmVZ2KMwuHRRbdZUZl%1f/0LoSAuC0wyfKMhiohXNPGWY7wyQbqr2XVyKtjpFk="); + public static readonly ApiKey BitlyClientSecret = ApiKey.Create("%e%NOCzRjTNRC64Hx0d6e4spA==%XJjn/yAsTsmtgLMdFpjptss66DFh15nvV+Ff2omHxYk0tKyc5Wn5qFxVquAQ4Yg3%yJnMWwcs/FfTYJZ1Wg3r7m0TMogAPj85ViUXImom890="); //===================================================================== // TINAMI @@ -162,7 +162,7 @@ internal static class ApplicationSettings /// /// TINAMI APIキー /// - public static readonly ApiKey TINAMIApiKey = ApiKey.Create("%e%OA+C4u5v/9Oc2xIOEKt6Ng==%xLrMgeXaYSIaW5LYEA2viA==%/0bWO/UMCYH2BRxPKvi7JCW/CXxp/JmincpFNRlvhOQ="); + public static readonly ApiKey TINAMIApiKey = ApiKey.Create("%e%5wz/IYAfWvY9y731F3yCIQ==%7y8i0qD9AF4DqFWjY1zn1w==%eVU155W/1sr3ZPDcuRMGTpSQyGXF4egWFto/HzBdGJ4="); //===================================================================== // Microsoft Translator API (Cognitive Service) @@ -171,7 +171,7 @@ internal static class ApplicationSettings /// /// Translator Text API Subscription Key /// - public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("%e%ysNsopqjk7fEikJNfX3ZtQ==%ZS4Gzq9PSUzBGKabQWi5To2nVLl8R3D+i/7nj5dACFAkBvQkxmrgJCnvON9cdF/+%1bayEnkpd4gbcyTTwB9PILWdku3YS52FuHskkpIhlXQ="); + public static readonly ApiKey TranslatorSubscriptionKey = ApiKey.Create("%e%N0EPwqCbM0qiNX4h7VsrXQ==%uOf/IdH2RO6fTgrhrvXuJJ7IT+R44aS7ROY3aQFCqqrLHru4fZh2hJAEoAI239BY%p26g6G/ANsAf+1Xq/iLE2zuTwA4ok/zZ61SQkvqqTZ8="); //===================================================================== // Imgur @@ -180,12 +180,12 @@ internal static class ApplicationSettings /// /// Imgur Client ID /// - public static readonly ApiKey ImgurClientId = ApiKey.Create("%e%YQirOk0lRw8zjhrTPlyRrQ==%ysNbeo//DruosSIzXquwiw==%126uNNTZshuw/SW9hd1ME/KCMpKSfjeboSRtQRfVQwc="); + public static readonly ApiKey ImgurClientId = ApiKey.Create("%e%kNnrm5hWWwTPZ9MgqF9osg==%yCbBWxtlZmzdBgR1v57+uQ==%FHJAyKZ7w4c0OWzgU86nq7p2J5trJVjOjdFSOfIArU0="); /// /// Imgur Client Secret /// - public static readonly ApiKey ImgurClientSecret = ApiKey.Create("%e%+IHTR8uXh2Mig6zGkawjeA==%vYQDZ+Tw5Rol4mQRC/yzXywuaNPWgoL5kLIg5VdUiCnSX5EPGQC5+QUkTzGz/fqv%+mOv8ekXLoZKe05yyXJ8Sx0cjuimoPQA30k/571wVRw="); + public static readonly ApiKey ImgurClientSecret = ApiKey.Create("%e%nLVIw/raU3ozrGmkfIk3Ig==%2iKGe1reB5p6VHkvrMkH1w==%lwwvuejEuy0eZZ9nS4BT1Jw7S7pkLktGPKzsfQErttw="); //===================================================================== // Mobypicture @@ -194,7 +194,7 @@ internal static class ApplicationSettings /// /// Mobypicture Developer Key /// - public static readonly ApiKey MobypictureKey = ApiKey.Create("%e%1FQ6vgxHCduEDyyJ7UK1ug==%xNBXVlAgJ8XiXZ1LSgGvEL1Vk1m4EzQ+6T/yigTgRHw=%xCAlJ1gBpe8G1Us6wXZBkYGxccFvRyRhmnFM4ocuhHQ="); + public static readonly ApiKey MobypictureKey = ApiKey.Create("%e%G9elTyjHy18MCbUvVqHKIw==%TDUSyoO4HS5SX+t50cUlRQ5tIFDib0xjsnCKX+K/+DI=%s2qPqrxXrmi8oeQWoeigqNDbecUAqcYuv2LPRFDLwJk="); //===================================================================== // Tumblr @@ -203,6 +203,6 @@ internal static class ApplicationSettings /// /// Tumblr OAuth Consumer Key /// - public static readonly ApiKey TumblrConsumerKey = ApiKey.Create("%e%1jQuOn2+l8O9i0/ld/VV5Q==%SiBRxJWj4Cbq/btPs63Rr2xOyw4XgTlV+lVkHkvIapBRkUaqGJxV7R/j5ljX+QW0ruBXNy+cpZFeEZFfB2jvSQ==%3GdYHow0pAlPQRY/wquX1AaxjzSabStRj8zbTXct1S4="); + public static readonly ApiKey TumblrConsumerKey = ApiKey.Create("%e%YEjYH0khBP52A9mbP6XMQQ==%V2B5KP9JJrE0A/o1+9fyq1OCnM4Ez1D8Qd3sVaeRKmvNIq8pY76pQB1R2PFMMI1nLZCCUH2PyA959490ujuvig==%GD8FiQzBOUM9lQta+1oTYs1ANE9Qp7+2XamfyQGmiMs="); } } diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 0a9786de8..3eeb21e18 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -5,11 +5,11 @@ // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 // アセンブリに関連付けられている情報を変更するには、 // これらの属性値を変更してください。 -[assembly: AssemblyTitle("OpenTween (dev)")] +[assembly: AssemblyTitle("OpenTween")] [assembly: AssemblyDescription("Client of Twitter. Free software(GPLv3)")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("OpenTween (dev)")] +[assembly: AssemblyProduct("OpenTween")] [assembly: AssemblyCopyright("(C) 2011 OpenTween contributors")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] From 9111810b93576c9d4cf5e4cbe9a2ffbba03cbb3d Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 03:14:58 +0900 Subject: [PATCH 066/402] =?UTF-8?q?Twemoji=E3=81=AE=E6=AD=A3=E8=A6=8F?= =?UTF-8?q?=E8=A1=A8=E7=8F=BE=E3=83=91=E3=82=BF=E3=83=BC=E3=83=B3=E3=82=92?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/twitter/twemoji-parser/blob/v13.1.0/src/lib/regex.js#L5 --- OpenTween.Tests/TweetExtractorTest.cs | 12 ++++++++++++ OpenTween/Resources/ChangeLog.txt | 2 ++ OpenTween/TweetExtractor.cs | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/OpenTween.Tests/TweetExtractorTest.cs b/OpenTween.Tests/TweetExtractorTest.cs index a2869a9b6..1c03a8e91 100644 --- a/OpenTween.Tests/TweetExtractorTest.cs +++ b/OpenTween.Tests/TweetExtractorTest.cs @@ -292,6 +292,18 @@ public void ExtractEmojiEntities_Unicode12Test() Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f9c5.png", entity.Url); } + [Fact] + public void ExtractEmojiEntities_Unicode13Test() + { + // Unicode 13.0 で追加された絵文字 + var origText = "🥷"; // U+1F977 (NINJA) + var entity = TweetExtractor.ExtractEmojiEntities(origText).Single(); + + Assert.Equal(new[] { 0, 1 }, entity.Indices); + Assert.Equal("🥷", entity.Text); + Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f977.png", entity.Url); + } + [Fact] public void ExtractEmojiEntities_EmojiModifiers_CombiningTest() { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index c68dd363e..23a946466 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,8 @@ ==== Ver 2.4.4-dev(2019/xx/xx) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました + * NEW: Twemoji 13.1 に対応しました + - Unicode 13.0 で追加された絵文字が表示されるようになります * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 * CHG: Instagramのサムネイルを表示するURLのパターンを追加 * CHG: YouTubeのサムネイルを表示するURLのパターンを追加 (thx @Hawklaver!) diff --git a/OpenTween/TweetExtractor.cs b/OpenTween/TweetExtractor.cs index 737f26acc..97e0d7b3a 100644 --- a/OpenTween/TweetExtractor.cs +++ b/OpenTween/TweetExtractor.cs @@ -34,7 +34,7 @@ namespace OpenTween { public static class TweetExtractor { - public static readonly Regex EmojiPattern = new Regex(@"/(?:\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c\udffb|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c\udffb|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c\udffb|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb\udffc]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udffd]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d])|(?:\ud83d[\udc68\udc69])(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a-\udc6d\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5\udeeb\udeec\udef4-\udefa\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd71\udd73-\udd76\udd7a-\udda2\udda5-\uddaa\uddae-\uddb4\uddb7\uddba\uddbc-\uddca\uddd0\uddde-\uddff\ude70-\ude73\ude78-\ude7a\ude80-\ude82\ude90-\ude95]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f"); + public static readonly Regex EmojiPattern = new Regex(@"(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f"); /// /// テキストから URL を抽出して返します From 008afa86e40139bf0eb5089beb0d2aadc943a883 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 04:08:02 +0900 Subject: [PATCH 067/402] =?UTF-8?q?OpenTween=20v2.5.0=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 28 ++++++++++------------ OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 0a9786de8..c51d30bbb 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.4.3.1")] +[assembly: AssemblyVersion("2.5.0.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 885fe2fcb..0d982b67c 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,21 +571,19 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Ver 2.4.4-dev(2019/xx/xx) - /// - ///==== Ver 2.4.3(2019/12/06) - /// * FIX: 関連発言表示のタブを読み込み中に閉じるとエラーが発生する不具合を修正 - /// * FIX: 操作メニューの「タブ振り分けルール作成」から新規タブを作成するとエラーが発生する不具合を修正 - /// - ///==== Ver 2.4.2(2019/10/23) - /// * FIX: タブ更新時にエラーが発生するとプロセスが異常終了する場合がある不具合を修正 - /// * FIX: エラー発生時にステータスバーの縦幅が2行分に広がり戻らなくなる場合がある不具合を修正 - /// * FIX: 表示中のタブの名前を変更するとエラーが発生する不具合を修正 - /// - ///==== Ver 2.4.1(2019/09/25) - /// * FIX: 「タブを一覧の下に表示する」を無効にすると起動時にエラーが発生する不具合を修正 (thx @mulsys!) - /// * FIX: 発言一覧の選択状態が正しく描画されない不具合を修正 - /// * FIX: 更新間隔を0秒に設定した場合に自動更新が停止されない不具合を修正 (thx [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + ///==== Ver 2.5.0(2022/02/05) + /// * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました + /// * NEW: Twemoji 13.1 に対応しました + /// - Unicode 13.0 で追加された絵文字が表示されるようになります + /// * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 + /// * CHG: Instagramのサムネイルを表示するURLのパターンを追加 + /// * CHG: YouTubeのサムネイルを表示するURLのパターンを追加 (thx @Hawklaver!) + /// * CHG: UserStreams関係の機能を削除 + /// * CHG: 設定画面にある通知関係の項目の配置を移動 + /// * CHG: タブ別の新着通知表示のデフォルト設定を変更 + /// * Reply, DM タブ以外は新着通知表示がデフォルトでオフになります(従来はタブの種別に関わらずデフォルトでオン) + /// * CHG: 「Listの発言取得に公式RTを含める」のデフォルト設定をオンに変更 + /// * CHG: POSTキーのデフォルト設定を [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 23a946466..6563c4a15 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Ver 2.4.4-dev(2019/xx/xx) +==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました * NEW: Twemoji 13.1 に対応しました - Unicode 13.0 で追加された絵文字が表示されるようになります From 90535723a4e59ddcc1cd464cdb91f34367fe8872 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Feb 2022 04:12:23 +0900 Subject: [PATCH 068/402] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.5.1-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 5 +++-- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index c51d30bbb..95cc20ba3 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.5.0.0")] +[assembly: AssemblyVersion("2.5.0.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 0d982b67c..201f93ff3 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,6 +571,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Ver 2.5.1-dev(2022/xx/xx) + /// ///==== Ver 2.5.0(2022/02/05) /// * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました /// * NEW: Twemoji 13.1 に対応しました @@ -582,8 +584,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * CHG: 設定画面にある通知関係の項目の配置を移動 /// * CHG: タブ別の新着通知表示のデフォルト設定を変更 /// * Reply, DM タブ以外は新着通知表示がデフォルトでオフになります(従来はタブの種別に関わらずデフォルトでオン) - /// * CHG: 「Listの発言取得に公式RTを含める」のデフォルト設定をオンに変更 - /// * CHG: POSTキーのデフォルト設定を [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * CHG: 「Listの発言取得に公式RTを含める」のデフォル [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 6563c4a15..491103dae 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Ver 2.5.1-dev(2022/xx/xx) + ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました * NEW: Twemoji 13.1 に対応しました diff --git a/appveyor.yml b/appveyor.yml index 62f169cf0..47dd0f982 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.4.3.{build} +version: 2.5.0.{build} os: Visual Studio 2019 From aca11200819e4c91428cee9ab8de870a63aca253 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 8 Feb 2022 18:10:05 +0900 Subject: [PATCH 069/402] =?UTF-8?q?RT=E3=81=97=E3=81=9F=E4=BA=BA=E3=81=AE?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3=E3=82=92?= =?UTF-8?q?=E9=96=8B=E3=81=91=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Tween.Designer.cs | 36 ++++++++++++++++++++++++++++++++++++ OpenTween/Tween.cs | 30 ++++++++++++++++++++++++++++-- OpenTween/Tween.en.resx | 8 ++++++++ OpenTween/Tween.resx | 16 ++++++++++++++++ 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index f9ce2098d..ca43f159d 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -107,6 +107,8 @@ private void InitializeComponent() this.ShowProfMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShowRelatedStatusesMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); this.ShowUserTimelineToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ShowRetweeterProfMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ShowRetweeterUserTimelineToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenHomeOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenFavOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -242,6 +244,8 @@ private void InitializeComponent() this.ShowProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShowRelatedStatusesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ShowRetweeterProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ShowRetweeterUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripMenuItem6 = new System.Windows.Forms.ToolStripMenuItem(); this.MoveToHomeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.MoveToFavToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -919,6 +923,8 @@ private void InitializeComponent() this.OpenOpMenuItem, this.CreateRuleOpMenuItem, this.ListManageMenuItem, + this.ShowRetweeterProfMenuItem, + this.ShowRetweeterUserTimelineToolStripMenuItem, this.ToolStripSeparator26, this.ChangeReadOpMenuItem, this.JumpReadOpMenuItem, @@ -1019,6 +1025,18 @@ private void InitializeComponent() resources.ApplyResources(this.ShowUserTimelineToolStripMenuItem, "ShowUserTimelineToolStripMenuItem"); this.ShowUserTimelineToolStripMenuItem.Click += new System.EventHandler(this.ShowUserTimelineToolStripMenuItem_Click); // + // ShowRetweeterProfMenuItem + // + this.ShowRetweeterProfMenuItem.Name = "ShowRetweeterProfMenuItem"; + resources.ApplyResources(this.ShowRetweeterProfMenuItem, "ShowRetweeterProfMenuItem"); + this.ShowRetweeterProfMenuItem.Click += new System.EventHandler(this.ShowRetweeterProfileMenuItem_Click); + // + // ShowRetweeterUserTimelineToolStripMenuItem + // + this.ShowRetweeterUserTimelineToolStripMenuItem.Name = "ShowRetweeterUserTimelineToolStripMenuItem"; + resources.ApplyResources(this.ShowRetweeterUserTimelineToolStripMenuItem, "ShowRetweeterUserTimelineToolStripMenuItem"); + this.ShowRetweeterUserTimelineToolStripMenuItem.Click += new System.EventHandler(this.ShowRetweeterUserTimelineToolStripMenuItem_Click); + // // OpenOpMenuItem // this.OpenOpMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -1841,6 +1859,8 @@ private void InitializeComponent() this.ToolStripMenuItem6, this.ToolStripMenuItem7, this.ListManageUserContextToolStripMenuItem2, + this.ShowRetweeterProfileMenuItem, + this.ShowRetweeterUserTimelineContextMenuItem, this.ToolStripSeparator4, this.ToolStripMenuItem11, this.JumpUnreadMenuItem, @@ -1942,6 +1962,18 @@ private void InitializeComponent() resources.ApplyResources(this.ShowUserTimelineContextMenuItem, "ShowUserTimelineContextMenuItem"); this.ShowUserTimelineContextMenuItem.Click += new System.EventHandler(this.ShowUserTimelineToolStripMenuItem_Click); // + // ShowRetweeterProfileMenuItem + // + this.ShowRetweeterProfileMenuItem.Name = "ShowRetweeterProfileMenuItem"; + resources.ApplyResources(this.ShowRetweeterProfileMenuItem, "ShowRetweeterProfileMenuItem"); + this.ShowRetweeterProfileMenuItem.Click += new System.EventHandler(this.ShowRetweeterProfileMenuItem_Click); + // + // ShowRetweeterUserTimelineContextMenuItem + // + this.ShowRetweeterUserTimelineContextMenuItem.Name = "ShowRetweeterUserTimelineContextMenuItem"; + resources.ApplyResources(this.ShowRetweeterUserTimelineContextMenuItem, "ShowRetweeterUserTimelineContextMenuItem"); + this.ShowRetweeterUserTimelineContextMenuItem.Click += new System.EventHandler(this.ShowRetweeterUserTimelineToolStripMenuItem_Click); + // // ToolStripMenuItem6 // this.ToolStripMenuItem6.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -2193,6 +2225,8 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripMenuItem ShowProfMenuItem; internal System.Windows.Forms.ToolStripMenuItem ShowRelatedStatusesMenuItem2; internal System.Windows.Forms.ToolStripMenuItem ShowUserTimelineToolStripMenuItem; + internal System.Windows.Forms.ToolStripMenuItem ShowRetweeterProfMenuItem; + internal System.Windows.Forms.ToolStripMenuItem ShowRetweeterUserTimelineToolStripMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenOpMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenHomeOpMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenFavOpMenuItem; @@ -2311,6 +2345,8 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripMenuItem ShowProfileMenuItem; internal System.Windows.Forms.ToolStripMenuItem ShowRelatedStatusesMenuItem; internal System.Windows.Forms.ToolStripMenuItem ShowUserTimelineContextMenuItem; + internal System.Windows.Forms.ToolStripMenuItem ShowRetweeterProfileMenuItem; + internal System.Windows.Forms.ToolStripMenuItem ShowRetweeterUserTimelineContextMenuItem; internal System.Windows.Forms.ToolStripMenuItem ToolStripMenuItem6; internal System.Windows.Forms.ToolStripMenuItem MoveToHomeToolStripMenuItem; internal System.Windows.Forms.ToolStripMenuItem MoveToFavToolStripMenuItem; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 3b1e8e7e0..0e0c049ff 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -3830,6 +3830,15 @@ private async Task ShowUserTimeline() await this.AddNewTabForUserTimeline(post.ScreenName); } + + private async Task ShowRetweeterTimeline() + { + var retweetedBy = this.CurrentPost?.RetweetedBy; + if (retweetedBy == null || !this.ExistCurrentPost) return; + await this.AddNewTabForUserTimeline(retweetedBy); + } + + private void SearchComboBox_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) @@ -10357,6 +10366,8 @@ public void SetPermanentHashtag(string hashtag) private void MenuItemOperate_DropDownOpening(object sender, EventArgs e) { + var tab = this.CurrentTab; + var post = this.CurrentPost; if (!this.ExistCurrentPost) { this.ReplyOpMenuItem.Enabled = false; @@ -10364,6 +10375,8 @@ private void MenuItemOperate_DropDownOpening(object sender, EventArgs e) this.DmOpMenuItem.Enabled = false; this.ShowProfMenuItem.Enabled = false; this.ShowUserTimelineToolStripMenuItem.Enabled = false; + this.ShowRetweeterProfMenuItem.Enabled = false; + this.ShowRetweeterUserTimelineToolStripMenuItem.Enabled = false; this.ListManageMenuItem.Enabled = false; this.OpenFavOpMenuItem.Enabled = false; this.CreateTabRuleOpMenuItem.Enabled = false; @@ -10379,6 +10392,9 @@ private void MenuItemOperate_DropDownOpening(object sender, EventArgs e) this.DmOpMenuItem.Enabled = true; this.ShowProfMenuItem.Enabled = true; this.ShowUserTimelineToolStripMenuItem.Enabled = true; + this.ShowRetweeterProfMenuItem.Enabled + = this.ShowRetweeterUserTimelineToolStripMenuItem.Enabled + = post?.RetweetedByUserId != null; this.ListManageMenuItem.Enabled = true; this.OpenFavOpMenuItem.Enabled = true; this.CreateTabRuleOpMenuItem.Enabled = true; @@ -10388,8 +10404,6 @@ private void MenuItemOperate_DropDownOpening(object sender, EventArgs e) this.UnreadOpMenuItem.Enabled = true; } - var tab = this.CurrentTab; - var post = this.CurrentPost; if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post == null || post.IsDm) { this.FavOpMenuItem.Enabled = false; @@ -10599,6 +10613,15 @@ private async void ShowProfileMenuItem_Click(object sender, EventArgs e) } } + private async void ShowRetweeterProfileMenuItem_Click(object sender, EventArgs e) + { + var retweetedBy = this.CurrentPost?.RetweetedBy; + if (retweetedBy != null) + { + await this.ShowUserStatus(retweetedBy, false); + } + } + private async void RtCountMenuItem_Click(object sender, EventArgs e) { var post = this.CurrentPost; @@ -10939,6 +10962,9 @@ private bool ExistCurrentPost private async void ShowUserTimelineToolStripMenuItem_Click(object sender, EventArgs e) => await this.ShowUserTimeline(); + private async void ShowRetweeterUserTimelineToolStripMenuItem_Click(object sender, EventArgs e) + => await this.ShowRetweeterTimeline(); + private string GetUserIdFromCurPostOrInput(string caption) { var id = this.CurrentPost?.ScreenName ?? ""; diff --git a/OpenTween/Tween.en.resx b/OpenTween/Tween.en.resx index 60d9549b5..4f1f7c4b7 100644 --- a/OpenTween/Tween.en.resx +++ b/OpenTween/Tween.en.resx @@ -415,6 +415,14 @@ Related Posts (&G) 347, 24 Related Posts (&G) + 258, 24 + Retweeter &Profile + 347, 24 + Retweeter &Profile + 258, 24 + &Retweeter's updates + 347, 24 + Retweeter's updates 258, 24 &User's updates 347, 24 diff --git a/OpenTween/Tween.resx b/OpenTween/Tween.resx index 73a72e978..5deab6f97 100644 --- a/OpenTween/Tween.resx +++ b/OpenTween/Tween.resx @@ -330,6 +330,14 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShowRelatedStatusesMenuItem2 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowProfileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowProfMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowUserTimelineContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowUserTimelineToolStripMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShowUserTimelineContextMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShowUserTimelineToolStripMenuItem @@ -1066,6 +1074,14 @@ 関連発言表示(&G) 313, 22 関連発言表示(&G) + 258, 24 + RT元のプロフィール表示 + 347, 24 + RT元のプロフィール表示 + 258, 24 + RT元ユーザーのタイムラインを表示 + 347, 24 + RT元ユーザーのタイムラインを表示 241, 22 ユーザーのタイムラインを表示 Ctrl+U From 8cf26ea73a3111d790b10c9346ba32c611d35873 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Tue, 8 Feb 2022 18:39:49 +0900 Subject: [PATCH 070/402] =?UTF-8?q?PostClassTest=20=E3=82=92=E4=B8=A6?= =?UTF-8?q?=E5=88=97=E5=AE=9F=E8=A1=8C=E3=81=99=E3=82=8B=E3=81=A8=E5=A4=B1?= =?UTF-8?q?=E6=95=97=E3=81=97=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PostClass を static に保持しないようにする --- OpenTween.Tests/Models/PostClassTest.cs | 40 +++++++++++++++++-------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index 63c115b1d..3d2291307 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -32,29 +32,45 @@ namespace OpenTween.Models { public class PostClassTest { + class PostClassGroup + { + private Dictionary testCases; + public PostClassGroup(params TestPostClass[] postClasses) + { + testCases = new Dictionary(); + foreach (var p in postClasses) + { + p.Group = this; + testCases.Add(p.StatusId, p); + } + } + public PostClass this[long id] => testCases[id]; + } class TestPostClass : PostClass { + public PostClassGroup? Group; protected override PostClass RetweetSource { get { var retweetedId = this.RetweetedId!.Value; + var group = this.Group; + if (group == null) + throw new InvalidOperationException("TestPostClass needs group"); - return PostClassTest.TestCases[retweetedId]; + return group[retweetedId]; } } } - private static Dictionary TestCases; + private PostClassGroup PostGroup; - static PostClassTest() + public PostClassTest() { - PostClassTest.TestCases = new Dictionary - { - [1L] = new TestPostClass { StatusId = 1L }, - [2L] = new TestPostClass { StatusId = 2L, IsFav = true }, - [3L] = new TestPostClass { StatusId = 3L, IsFav = false, RetweetedId = 2L }, - }; + this.PostGroup = new PostClassGroup( + new TestPostClass { StatusId = 1L }, + new TestPostClass { StatusId = 2L, IsFav = true }, + new TestPostClass { StatusId = 3L, IsFav = false, RetweetedId = 2L }); } [Fact] @@ -81,7 +97,7 @@ public void TextSingleLineTest(string text, string expected) [InlineData(2L, true)] [InlineData(3L, true)] public void GetIsFavTest(long statusId, bool expected) - => Assert.Equal(expected, PostClassTest.TestCases[statusId].IsFav); + => Assert.Equal(expected, PostGroup[statusId].IsFav); [Theory] [InlineData(2L, true)] @@ -90,13 +106,13 @@ public void GetIsFavTest(long statusId, bool expected) [InlineData(3L, false)] public void SetIsFavTest(long statusId, bool isFav) { - var post = PostClassTest.TestCases[statusId]; + var post = PostGroup[statusId]; post.IsFav = isFav; Assert.Equal(isFav, post.IsFav); if (post.RetweetedId != null) - Assert.Equal(isFav, PostClassTest.TestCases[post.RetweetedId.Value].IsFav); + Assert.Equal(isFav, PostGroup[post.RetweetedId.Value].IsFav); } [Theory] From 17ac69c581debcf40f7bd5f598152864b8c7eab2 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 12 Feb 2022 07:18:25 +0900 Subject: [PATCH 071/402] =?UTF-8?q?ChangeLog=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit aca11200819e4c91428cee9ab8de870a63aca253 の変更を反映 --- OpenTween/Resources/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 491103dae..8a7e6b2e8 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Ver 2.5.1-dev(2022/xx/xx) + * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました From 05a6a2a88de37c9a97cde929da908800def77b82 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 13 Feb 2022 19:23:34 +0900 Subject: [PATCH 072/402] =?UTF-8?q?StyleCop.Analyzer=E3=82=92=E5=B0=8E?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 3 +++ OpenTween.Tests/OpenTween.Tests.csproj | 7 +++++++ OpenTween.sln | 9 +++++++++ OpenTween/OpenTween.csproj | 8 ++++++++ stylecop.json | 5 +++++ 5 files changed, 32 insertions(+) create mode 100644 .editorconfig create mode 100644 stylecop.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..d538aa3c6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,3 @@ +[*.cs] +indent_style = space +tab_width = 4 diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index 999b4327e..36821621d 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -7,6 +7,9 @@ enable true + + + @@ -23,6 +26,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + all diff --git a/OpenTween.sln b/OpenTween.sln index 0f6d39232..f85960885 100644 --- a/OpenTween.sln +++ b/OpenTween.sln @@ -7,6 +7,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTween", "OpenTween\Open EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTween.Tests", "OpenTween.Tests\OpenTween.Tests.csproj", "{18A32642-A8F3-425B-978D-0C6F630EDDE8}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8B1F66B9-8C63-4236-AB06-F5F19C20EE71}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + stylecop.json = stylecop.json + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -39,4 +45,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DDF8A3B3-E5D3-4853-84B5-3B3ADCB356C0} + EndGlobalSection EndGlobal diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index b0ec82a31..5c55c14b1 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -724,6 +724,9 @@ LICENSE.LGPL-3 Always + + stylecop.json + Designer @@ -757,6 +760,11 @@ 1.0.1 + + 1.2.0-beta.406 + runtime; build; native; contentfiles; analyzers; buildtransitive + all + " + "
";
         private const string detailHtmlFormatFooterMono = "
"; - private const string detailHtmlFormatHeaderColor = + private const string detailHtmlFormatHeaderColor = "" + "" + "
";
-        private const string detailHtmlFormatFooterMono = "
"; - private const string detailHtmlFormatHeaderColor = + private const string DetailHtmlFormatFooterMono = ""; + private const string DetailHtmlFormatHeaderColor = "" + "" + "

"; - private const string detailHtmlFormatFooterColor = "

"; + private const string DetailHtmlFormatFooterColor = "

"; private string detailHtmlFormatHeader = null!; private string detailHtmlFormatFooter = null!; @@ -373,13 +373,13 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ private bool preventSmsCommand = true; // URL短縮のUndo用 - private struct urlUndo + private struct UrlUndo { public string Before; public string After; } - private List? urlUndoBuffer = null; + private List? urlUndoBuffer = null; private readonly struct ReplyChain { @@ -426,20 +426,20 @@ internal enum SEARCHTYPE private class StatusTextHistory { - public string status = ""; - public (long StatusId, string ScreenName)? inReplyTo = null; + public string Status { get; } = ""; + public (long StatusId, string ScreenName)? InReplyTo { get; } = null; /// 画像投稿サービス名 - public string imageService = ""; + public string ImageService { get; set; } = ""; - public IMediaItem[]? mediaItems = null; + public IMediaItem[]? MediaItems { get; set; } = null; public StatusTextHistory() { } public StatusTextHistory(string status, (long StatusId, string ScreenName)? inReplyTo) { - this.status = status; - this.inReplyTo = inReplyTo; + this.Status = status; + this.InReplyTo = inReplyTo; } } @@ -1191,7 +1191,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.List] = () => this.InvokeAsync(() => this.RefreshTabAsync()); this.timelineScheduler.UpdateFunc[TimelineSchedulerTaskType.Config] = () => this.InvokeAsync(() => Task.WhenAll(new[] { - this.doGetFollowersMenu(), + this.DoGetFollowersMenu(), this.RefreshBlockIdsAsync(), this.RefreshMuteUserIdsAsync(), this.RefreshNoRetweetIdsAsync(), @@ -1230,13 +1230,13 @@ private void InitDetailHtmlFormat() { if (SettingManager.Common.IsMonospace) { - this.detailHtmlFormatHeader = detailHtmlFormatHeaderMono; - this.detailHtmlFormatFooter = detailHtmlFormatFooterMono; + this.detailHtmlFormatHeader = DetailHtmlFormatHeaderMono; + this.detailHtmlFormatFooter = DetailHtmlFormatFooterMono; } else { - this.detailHtmlFormatHeader = detailHtmlFormatHeaderColor; - this.detailHtmlFormatFooter = detailHtmlFormatFooterColor; + this.detailHtmlFormatHeader = DetailHtmlFormatHeaderColor; + this.detailHtmlFormatFooter = DetailHtmlFormatFooterColor; } this.detailHtmlFormatHeader = this.detailHtmlFormatHeader @@ -1357,15 +1357,15 @@ private void TimerInterval_Changed(object sender, IntervalChangedEventArgs e) private void RefreshTimelineScheduler() { - static TimeSpan intervalSecondsOrDisabled(int seconds) + static TimeSpan IntervalSecondsOrDisabled(int seconds) => seconds == 0 ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(seconds); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = intervalSecondsOrDisabled(SettingManager.Common.TimelinePeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Mention] = intervalSecondsOrDisabled(SettingManager.Common.ReplyPeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Dm] = intervalSecondsOrDisabled(SettingManager.Common.DMPeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.PublicSearch] = intervalSecondsOrDisabled(SettingManager.Common.PubSearchPeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.User] = intervalSecondsOrDisabled(SettingManager.Common.UserTimelinePeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.List] = intervalSecondsOrDisabled(SettingManager.Common.ListsPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = IntervalSecondsOrDisabled(SettingManager.Common.TimelinePeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Mention] = IntervalSecondsOrDisabled(SettingManager.Common.ReplyPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Dm] = IntervalSecondsOrDisabled(SettingManager.Common.DMPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.PublicSearch] = IntervalSecondsOrDisabled(SettingManager.Common.PubSearchPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.User] = IntervalSecondsOrDisabled(SettingManager.Common.UserTimelinePeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.List] = IntervalSecondsOrDisabled(SettingManager.Common.ListsPeriod); this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Config] = TimeSpan.FromHours(6); this.timelineScheduler.UpdateAfterSystemResume = TimeSpan.FromSeconds(30); @@ -1418,7 +1418,7 @@ private void RefreshTimeline() out var newMentionOrDm, out var isDelete); - if (MyCommon._endingFlag) return; + if (MyCommon.EndingFlag) return; // リストに反映&選択状態復元 foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) @@ -2049,8 +2049,8 @@ private void StatusTextHistoryBack() this._hisIdx = 0; var historyItem = this._history[this._hisIdx]; - this.inReplyTo = historyItem.inReplyTo; - this.StatusText.Text = historyItem.status; + this.inReplyTo = historyItem.InReplyTo; + this.StatusText.Text = historyItem.Status; this.StatusText.SelectionStart = this.StatusText.Text.Length; } @@ -2064,8 +2064,8 @@ private void StatusTextHistoryForward() this._hisIdx = this._history.Count - 1; var historyItem = this._history[this._hisIdx]; - this.inReplyTo = historyItem.inReplyTo; - this.StatusText.Text = historyItem.status; + this.inReplyTo = historyItem.InReplyTo; + this.StatusText.Text = historyItem.Status; this.StatusText.SelectionStart = this.StatusText.Text.Length; } @@ -2091,7 +2091,7 @@ private async void PostButton_Click(object sender, EventArgs e) { case DialogResult.Yes: this.StatusText.Text = ""; - await this.doReTweetOfficial(false); + await this.DoReTweetOfficial(false); return; case DialogResult.Cancel: return; @@ -2188,13 +2188,13 @@ private async void PostButton_Click(object sender, EventArgs e) private void EndToolStripMenuItem_Click(object sender, EventArgs e) { - MyCommon._endingFlag = true; + MyCommon.EndingFlag = true; this.Close(); } private void TweenMain_FormClosing(object sender, FormClosingEventArgs e) { - if (!SettingManager.Common.CloseToExit && e.CloseReason == CloseReason.UserClosing && MyCommon._endingFlag == false) + if (!SettingManager.Common.CloseToExit && e.CloseReason == CloseReason.UserClosing && MyCommon.EndingFlag == false) { // _endingFlag=false:フォームの×ボタン e.Cancel = true; @@ -2204,7 +2204,7 @@ private void TweenMain_FormClosing(object sender, FormClosingEventArgs e) { this._hookGlobalHotkey.UnregisterAllOriginalHotkey(); this._ignoreConfigSave = true; - MyCommon._endingFlag = true; + MyCommon.EndingFlag = true; this.timelineScheduler.Enabled = false; this.TimerRefreshIcon.Enabled = false; } @@ -3258,7 +3258,7 @@ private void ReplyStripMenuItem_Click(object sender, EventArgs e) private void DMStripMenuItem_Click(object sender, EventArgs e) => this.MakeReplyOrDirectStatus(false, false); - private async Task doStatusDelete() + private async Task DoStatusDelete() { var posts = this.CurrentTab.SelectedPosts; if (posts.Length == 0) @@ -3379,7 +3379,7 @@ await this.twitterApi.StatusesDestroy(post.StatusId) } private async void DeleteStripMenuItem_Click(object sender, EventArgs e) - => await this.doStatusDelete(); + => await this.DoStatusDelete(); private void ReadedStripMenuItem_Click(object sender, EventArgs e) { @@ -3456,8 +3456,8 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) settingDialog.ShowInTaskbar = showTaskbarIcon; settingDialog.IntervalChanged += this.TimerInterval_Changed; - settingDialog.tw = this.tw; - settingDialog.twitterApi = this.twitterApi; + settingDialog.Tw = this.tw; + settingDialog.TwitterApi = this.twitterApi; settingDialog.LoadConfig(SettingManager.Common, SettingManager.Local); @@ -3729,7 +3729,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) this.SaveConfigsAll(false); if (this.tw.UserId != oldUser.UserId) - await this.doGetFollowersMenu(); + await this.DoGetFollowersMenu(); } /// @@ -4367,7 +4367,7 @@ public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog, int offset, str var eHalf = ""; if (dialog.DialogResult == DialogResult.OK) { - if (!MyCommon.IsNullOrEmpty(dialog.inputText)) + if (!MyCommon.IsNullOrEmpty(dialog.InputText)) { if (selStart > 0) { @@ -4377,8 +4377,8 @@ public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog, int offset, str { eHalf = owner.Text.Substring(selStart); } - owner.Text = fHalf + dialog.inputText + eHalf; - owner.SelectionStart = selStart + dialog.inputText.Length; + owner.Text = fHalf + dialog.InputText + eHalf; + owner.SelectionStart = selStart + dialog.InputText.Length; } } else @@ -5375,8 +5375,8 @@ private void RunTweenUp() var pinfo = new ProcessStartInfo { UseShellExecute = true, - WorkingDirectory = MyCommon.settingPath, - FileName = Path.Combine(MyCommon.settingPath, "TweenUp3.exe"), + WorkingDirectory = MyCommon.SettingPath, + FileName = Path.Combine(MyCommon.SettingPath, "TweenUp3.exe"), Arguments = "\"" + Application.StartupPath + "\"", }; @@ -5522,7 +5522,7 @@ private void UpdateSelectedPost() this.DispSelectedPost(); } - public string createDetailHtml(string orgdata) + public string CreateDetailHtml(string orgdata) => this.detailHtmlFormatHeader + orgdata + this.detailHtmlFormatFooter; private void DispSelectedPost() @@ -5563,7 +5563,7 @@ private void DispSelectedPost(bool forceupdate) loadTasks.Add(this.tweetThumbnail1.ShowThumbnailAsync(currentPost, token)); } - async Task delayedTasks() + async Task DelayedTasks() { try { @@ -5573,7 +5573,7 @@ async Task delayedTasks() } // サムネイルの読み込みを待たずに次に選択されたツイートを表示するため await しない - _ = delayedTasks(); + _ = DelayedTasks(); } private async void MatomeMenuItem_Click(object sender, EventArgs e) @@ -5773,7 +5773,7 @@ private void InitializeShortcuts() .Do(() => this.MakeReplyOrDirectStatus(isAuto: false, isReply: true)), ShortcutCommand.Create(Keys.Control | Keys.D) - .Do(() => this.doStatusDelete()), + .Do(() => this.DoStatusDelete()), ShortcutCommand.Create(Keys.Control | Keys.M) .Do(() => this.MakeReplyOrDirectStatus(isAuto: false, isReply: false)), @@ -5782,10 +5782,10 @@ private void InitializeShortcuts() .Do(() => this.FavoriteChange(FavAdd: true)), ShortcutCommand.Create(Keys.Control | Keys.I) - .Do(() => this.doRepliedStatusOpen()), + .Do(() => this.DoRepliedStatusOpen()), ShortcutCommand.Create(Keys.Control | Keys.Q) - .Do(() => this.doQuoteOfficial()), + .Do(() => this.DoQuoteOfficial()), ShortcutCommand.Create(Keys.Control | Keys.B) .Do(() => this.ReadedStripMenuItem_Click(this.ReadedStripMenuItem, EventArgs.Empty)), @@ -5991,11 +5991,11 @@ private void InitializeShortcuts() .Do(() => this.GoBackSelectPostChain()), ShortcutCommand.Create(Keys.Alt | Keys.R) - .Do(() => this.doReTweetOfficial(isConfirm: true)), + .Do(() => this.DoReTweetOfficial(isConfirm: true)), ShortcutCommand.Create(Keys.Alt | Keys.P) .OnlyWhen(() => this.CurrentPost != null) - .Do(() => this.doShowUserStatus(this.CurrentPost!.ScreenName, ShowInputDialog: false)), + .Do(() => this.DoShowUserStatus(this.CurrentPost!.ScreenName, ShowInputDialog: false)), ShortcutCommand.Create(Keys.Alt | Keys.Up) .Do(() => this.tweetDetailsView.ScrollDownPostBrowser(forward: false)), @@ -6041,7 +6041,7 @@ private void InitializeShortcuts() .Do(() => this.ImageSelectMenuItem_Click(this.ImageSelectMenuItem, EventArgs.Empty)), ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.H) - .Do(() => this.doMoveToRTHome()), + .Do(() => this.DoMoveToRTHome()), ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.Up) .FocusedOn(FocusedControl.StatusText) @@ -6157,14 +6157,14 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Alt | Keys.Shift | Keys.R) .FocusedOn(FocusedControl.PostBrowser) - .Do(() => this.doReTweetUnofficial()), + .Do(() => this.DoReTweetUnofficial()), ShortcutCommand.Create(Keys.Alt | Keys.Shift | Keys.T) .OnlyWhen(() => this.ExistCurrentPost) .Do(() => this.tweetDetailsView.DoTranslation()), ShortcutCommand.Create(Keys.Alt | Keys.Shift | Keys.R) - .Do(() => this.doReTweetUnofficial()), + .Do(() => this.DoReTweetUnofficial()), ShortcutCommand.Create(Keys.Alt | Keys.Shift | Keys.C, Keys.Alt | Keys.Shift | Keys.Insert) .Do(() => this.CopyUserId()), @@ -8468,7 +8468,7 @@ private void SetMainWindowTitle() break; case MyCommon.DispTitleEnum.Post: if (this._history != null && this._history.Count > 1) - ttl.Append(this._history[this._history.Count - 2].status.Replace("\r\n", " ")); + ttl.Append(this._history[this._history.Count - 2].Status.Replace("\r\n", " ")); break; case MyCommon.DispTitleEnum.UnreadRepCount: ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText1, this._statuses.MentionTab.UnreadCount + this._statuses.DirectMessageTab.UnreadCount); @@ -8809,7 +8809,7 @@ private void SplitContainer1_SplitterMoved(object sender, SplitterEventArgs e) this.MarkSettingLocalModified(); } - private async Task doRepliedStatusOpen() + private async Task DoRepliedStatusOpen() { var currentPost = this.CurrentPost; if (this.ExistCurrentPost && currentPost != null && currentPost.InReplyToUser != null && currentPost.InReplyToStatusId != null) @@ -8838,7 +8838,7 @@ private async Task doRepliedStatusOpen() } private async void RepliedStatusOpenMenuItem_Click(object sender, EventArgs e) - => await this.doRepliedStatusOpen(); + => await this.DoRepliedStatusOpen(); private void SplitContainer2_Panel2_Resize(object sender, EventArgs e) { @@ -8917,7 +8917,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) // nico.ms使用、nicovideoにマッチしたら変換 if (SettingManager.Common.Nicoms && Regex.IsMatch(tmp, nico)) { - result = nicoms.Shorten(tmp); + result = Nicoms.Shorten(tmp); } else if (Converter_Type != MyCommon.UrlConverter.Nicoms) { @@ -8946,7 +8946,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) if (!MyCommon.IsNullOrEmpty(result)) { - var undotmp = new urlUndo(); + var undotmp = new UrlUndo(); // 短縮 URL が生成されるまでの間に投稿欄から元の URL が削除されていたら中断する var origUrlIndex = this.StatusText.Text.IndexOf(tmp, StringComparison.Ordinal); @@ -8962,7 +8962,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) if (this.urlUndoBuffer == null) { - this.urlUndoBuffer = new List(); + this.urlUndoBuffer = new List(); this.UrlUndoToolStripMenuItem.Enabled = true; } @@ -8985,7 +8985,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) var tmp = mt.Result("${url}"); if (tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase)) tmp = "http://" + tmp; - var undotmp = new urlUndo(); + var undotmp = new UrlUndo(); // 選んだURLを選択(?) this.StatusText.Select(this.StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length); @@ -8993,7 +8993,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) // nico.ms使用、nicovideoにマッチしたら変換 if (SettingManager.Common.Nicoms && Regex.IsMatch(tmp, nico)) { - result = nicoms.Shorten(tmp); + result = Nicoms.Shorten(tmp); } else if (Converter_Type != MyCommon.UrlConverter.Nicoms) { @@ -9044,7 +9044,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) if (this.urlUndoBuffer == null) { - this.urlUndoBuffer = new List(); + this.urlUndoBuffer = new List(); this.UrlUndoToolStripMenuItem.Enabled = true; } @@ -9056,7 +9056,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) return true; } - private void doUrlUndo() + private void DoUrlUndo() { if (this.urlUndoBuffer != null) { @@ -9100,7 +9100,7 @@ private async void UrlConvertAutoToolStripMenuItem_Click(object sender, EventArg } private void UrlUndoToolStripMenuItem_Click(object sender, EventArgs e) - => this.doUrlUndo(); + => this.DoUrlUndo(); private void NewPostPopMenuItem_CheckStateChanged(object sender, EventArgs e) { @@ -9589,11 +9589,11 @@ private async void TweenMain_Shown(object sender, EventArgs e) i += 1; if (i > 24) break; // 120秒間初期処理が終了しなかったら強制的に打ち切る - if (MyCommon._endingFlag) + if (MyCommon.EndingFlag) return; } - if (MyCommon._endingFlag) return; + if (MyCommon.EndingFlag) return; if (ApplicationSettings.VersionInfoUrl != null) { @@ -9636,19 +9636,19 @@ private async void TweenMain_Shown(object sender, EventArgs e) this.timelineScheduler.Enabled = true; } - private async Task doGetFollowersMenu() + private async Task DoGetFollowersMenu() { await this.RefreshFollowerIdsAsync(); this.DispSelectedPost(true); } private async void GetFollowersAllToolStripMenuItem_Click(object sender, EventArgs e) - => await this.doGetFollowersMenu(); + => await this.DoGetFollowersMenu(); private void ReTweetUnofficialStripMenuItem_Click(object sender, EventArgs e) - => this.doReTweetUnofficial(); + => this.DoReTweetUnofficial(); - private async Task doReTweetOfficial(bool isConfirm) + private async Task DoReTweetOfficial(bool isConfirm) { // 公式RT if (this.ExistCurrentPost) @@ -9703,13 +9703,13 @@ private async Task doReTweetOfficial(bool isConfirm) } private async void ReTweetStripMenuItem_Click(object sender, EventArgs e) - => await this.doReTweetOfficial(true); + => await this.DoReTweetOfficial(true); private async Task FavoritesRetweetOfficial() { if (!this.ExistCurrentPost) return; this._DoFavRetweetFlags = true; - var retweetTask = this.doReTweetOfficial(true); + var retweetTask = this.DoReTweetOfficial(true); if (this._DoFavRetweetFlags) { this._DoFavRetweetFlags = false; @@ -9733,7 +9733,7 @@ private async Task FavoritesRetweetUnofficial() if (!post.IsProtect && this._DoFavRetweetFlags) { this._DoFavRetweetFlags = false; - this.doReTweetUnofficial(); + this.DoReTweetUnofficial(); } await favoriteTask; @@ -10107,7 +10107,7 @@ internal async Task ShowFriendship(string[] ids) } private async void OwnStatusMenuItem_Click(object sender, EventArgs e) - => await this.doShowUserStatus(this.tw.Username, false); + => await this.DoShowUserStatus(this.tw.Username, false); // TwitterIDでない固定文字列を調べる(文字列検証のみ 実際に取得はしない) // URLから切り出した文字列を渡す @@ -10120,7 +10120,7 @@ public bool IsTwitterId(string name) return !this.tw.Configuration.NonUsernamePaths.Contains(name, StringComparer.InvariantCultureIgnoreCase); } - private void doQuoteOfficial() + private void DoQuoteOfficial() { var post = this.CurrentPost; if (this.ExistCurrentPost && post != null) @@ -10145,7 +10145,7 @@ private void doQuoteOfficial() } } - private void doReTweetUnofficial() + private void DoReTweetUnofficial() { // RT @id:内容 var post = this.CurrentPost; @@ -10177,7 +10177,7 @@ private void doReTweetUnofficial() } private void QuoteStripMenuItem_Click(object sender, EventArgs e) - => this.doQuoteOfficial(); + => this.DoQuoteOfficial(); private async void SearchButton_Click(object sender, EventArgs e) { @@ -10340,7 +10340,7 @@ private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) } } - private async Task doMoveToRTHome() + private async Task DoMoveToRTHome() { var post = this.CurrentPost; if (post != null && post.RetweetedId != null) @@ -10348,7 +10348,7 @@ private async Task doMoveToRTHome() } private async void MoveToRTHomeMenuItem_Click(object sender, EventArgs e) - => await this.doMoveToRTHome(); + => await this.DoMoveToRTHome(); private void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e) { @@ -10632,7 +10632,7 @@ private void NotifyIcon1_MouseMove(object sender, MouseEventArgs e) private async void UserStatusToolStripMenuItem_Click(object sender, EventArgs e) => await this.ShowUserStatus(this.CurrentPost?.ScreenName ?? ""); - private async Task doShowUserStatus(string id, bool ShowInputDialog) + private async Task DoShowUserStatus(string id, bool ShowInputDialog) { TwitterUser? user = null; @@ -10671,10 +10671,10 @@ private async Task doShowUserStatus(string id, bool ShowInputDialog) return; } - await this.doShowUserStatus(user); + await this.DoShowUserStatus(user); } - private async Task doShowUserStatus(TwitterUser user) + private async Task DoShowUserStatus(TwitterUser user) { using var userDialog = new UserInfoDialog(this, this.twitterApi); var showUserTask = userDialog.ShowUserAsync(user); @@ -10688,10 +10688,10 @@ private async Task doShowUserStatus(TwitterUser user) } internal Task ShowUserStatus(string id, bool ShowInputDialog) - => this.doShowUserStatus(id, ShowInputDialog); + => this.DoShowUserStatus(id, ShowInputDialog); internal Task ShowUserStatus(string id) - => this.doShowUserStatus(id, true); + => this.DoShowUserStatus(id, true); private async void ShowProfileMenuItem_Click(object sender, EventArgs e) { @@ -10761,7 +10761,7 @@ public TweenMain() this.tweetDetailsView.Owner = this; - this._hookGlobalHotkey.HotkeyPressed += this._hookGlobalHotkey_HotkeyPressed; + this._hookGlobalHotkey.HotkeyPressed += this.HookGlobalHotkey_HotkeyPressed; this.gh.NotifyClicked += this.GrowlHelper_Callback; // メイリオフォント指定時にタブの最小幅が広くなる問題の対策 @@ -10777,7 +10777,7 @@ public TweenMain() this.InitializeShortcuts(); } - private void _hookGlobalHotkey_HotkeyPressed(object sender, KeyEventArgs e) + private void HookGlobalHotkey_HotkeyPressed(object sender, KeyEventArgs e) { if ((this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized) && this.Visible && Form.ActiveForm == this) { @@ -11024,7 +11024,7 @@ private void CacheInfoMenuItem_Click(object sender, EventArgs e) private void TweenRestartMenuItem_Click(object sender, EventArgs e) { - MyCommon._endingFlag = true; + MyCommon.EndingFlag = true; try { this.Close(); @@ -11174,13 +11174,13 @@ private void ReplaceAppName() this.AboutMenuItem.Text = MyCommon.ReplaceAppName(this.AboutMenuItem.Text); } - private void tweetThumbnail1_ThumbnailLoading(object sender, EventArgs e) + private void TweetThumbnail_ThumbnailLoading(object sender, EventArgs e) => this.SplitContainer3.Panel2Collapsed = false; - private async void tweetThumbnail1_ThumbnailDoubleClick(object sender, ThumbnailDoubleClickEventArgs e) + private async void TweetThumbnail_ThumbnailDoubleClick(object sender, ThumbnailDoubleClickEventArgs e) => await this.OpenThumbnailPicture(e.Thumbnail); - private async void tweetThumbnail1_ThumbnailImageSearchClick(object sender, ThumbnailImageSearchEventArgs e) + private async void TweetThumbnail_ThumbnailImageSearchClick(object sender, ThumbnailImageSearchEventArgs e) => await MyCommon.OpenInBrowserAsync(this, e.ImageUrl); private async Task OpenThumbnailPicture(ThumbnailInfo thumbnail) @@ -11259,7 +11259,7 @@ private void LockListSortToolStripMenuItem_Click(object sender, EventArgs e) this.MarkSettingCommonModified(); } - private void tweetDetailsView_StatusChanged(object sender, TweetDetailsViewStatusChengedEventArgs e) + private void TweetDetailsView_StatusChanged(object sender, TweetDetailsViewStatusChengedEventArgs e) { if (!MyCommon.IsNullOrEmpty(e.StatusText)) { diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 2ac51bc2b..024b790b4 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -177,14 +177,14 @@ public async Task ShowPostDetails(PostClass post) } sb.Append("-----End PostClass Dump
"); - this.PostBrowser.DocumentText = this.Owner.createDetailHtml(sb.ToString()); + this.PostBrowser.DocumentText = this.Owner.CreateDetailHtml(sb.ToString()); return; } using (ControlTransaction.Update(this.PostBrowser)) { this.PostBrowser.DocumentText = - this.Owner.createDetailHtml(post.IsDeleted ? "(DELETED)" : post.Text); + this.Owner.CreateDetailHtml(post.IsDeleted ? "(DELETED)" : post.Text); this.PostBrowser.Document.Window.ScrollTo(0, 0); } @@ -283,7 +283,7 @@ private async Task AppendQuoteTweetAsync(PostClass post) var body = post.Text + string.Concat(loadingQuoteHtml) + loadingReplyHtml; using (ControlTransaction.Update(this.PostBrowser)) - this.PostBrowser.DocumentText = this.Owner.createDetailHtml(body); + this.PostBrowser.DocumentText = this.Owner.CreateDetailHtml(body); // 引用ツイートを読み込み var loadTweetTasks = quoteStatusIds.Select(x => this.CreateQuoteTweetHtml(x, isReply: false)).ToList(); @@ -300,7 +300,7 @@ private async Task AppendQuoteTweetAsync(PostClass post) body = post.Text + string.Concat(quoteHtmls); using (ControlTransaction.Update(this.PostBrowser)) - this.PostBrowser.DocumentText = this.Owner.createDetailHtml(body); + this.PostBrowser.DocumentText = this.Owner.CreateDetailHtml(body); } private async Task CreateQuoteTweetHtml(long statusId, bool isReply) @@ -374,7 +374,7 @@ private async Task DoTranslation(string str) langFrom: null, langTo: SettingManager.Common.TranslateLanguage); - this.PostBrowser.DocumentText = this.Owner.createDetailHtml(translatedText); + this.PostBrowser.DocumentText = this.Owner.CreateDetailHtml(translatedText); } catch (WebApiException e) { diff --git a/OpenTween/TweetExtractor.cs b/OpenTween/TweetExtractor.cs index 97e0d7b3a..ed5dc607d 100644 --- a/OpenTween/TweetExtractor.cs +++ b/OpenTween/TweetExtractor.cs @@ -47,7 +47,7 @@ public static IEnumerable ExtractUrls(string text) ///
public static IEnumerable ExtractUrlEntities(string text) { - var urlMatches = Regex.Matches(text, Twitter.rgUrl, RegexOptions.IgnoreCase).Cast(); + var urlMatches = Regex.Matches(text, Twitter.RgUrl, RegexOptions.IgnoreCase).Cast(); foreach (var m in urlMatches) { var before = m.Groups["before"].Value; @@ -59,17 +59,17 @@ public static IEnumerable ExtractUrlEntities(string text) var validUrl = false; if (protocol.Length == 0) { - if (Regex.IsMatch(before, Twitter.url_invalid_without_protocol_preceding_chars)) + if (Regex.IsMatch(before, Twitter.UrlInvalidWithoutProtocolPrecedingChars)) continue; string? lasturl = null; var last_url_invalid_match = false; - var domainMatches = Regex.Matches(domain, Twitter.url_valid_ascii_domain, RegexOptions.IgnoreCase).Cast(); + var domainMatches = Regex.Matches(domain, Twitter.UrlValidAsciiDomain, RegexOptions.IgnoreCase).Cast(); foreach (var mm in domainMatches) { lasturl = mm.Value; - last_url_invalid_match = Regex.IsMatch(lasturl, Twitter.url_invalid_short_domain, RegexOptions.IgnoreCase); + last_url_invalid_match = Regex.IsMatch(lasturl, Twitter.UrlInvalidShortDomain, RegexOptions.IgnoreCase); if (!last_url_invalid_match) { validUrl = true; diff --git a/OpenTween/TweetFormatter.cs b/OpenTween/TweetFormatter.cs index a881dee44..7001c1f59 100644 --- a/OpenTween/TweetFormatter.cs +++ b/OpenTween/TweetFormatter.cs @@ -68,7 +68,7 @@ private static IEnumerable AutoLinkHtmlInternal(string text, IEnumerable continue; // 区間が文字列長を越えている不正なエンティティを無視する if (curIndex != startIndex) - yield return t(e(text.Substring(curIndex, startIndex - curIndex))); + yield return T(E(text.Substring(curIndex, startIndex - curIndex))); var targetText = text.Substring(startIndex, endIndex - startIndex); @@ -81,13 +81,13 @@ private static IEnumerable AutoLinkHtmlInternal(string text, IEnumerable else if (entity is TwitterEntityEmoji emojiEntity) yield return FormatEmojiEntity(targetText, emojiEntity); else - yield return t(e(targetText)); + yield return T(E(targetText)); curIndex = endIndex; } if (curIndex != text.Length) - yield return t(e(text.Substring(curIndex))); + yield return T(E(text.Substring(curIndex))); } /// @@ -133,7 +133,7 @@ private static string FormatUrlEntity(string targetText, TwitterEntityUrl entity if (entity.DisplayUrl == null) { expandedUrl = MyCommon.ConvertToReadableUrl(targetText); - return "" + t(e(targetText)) + ""; + return "" + T(E(targetText)) + ""; } var linkUrl = entity.Url; @@ -154,30 +154,30 @@ private static string FormatUrlEntity(string targetText, TwitterEntityUrl entity } } - return "" + t(e(entity.DisplayUrl)) + ""; + return "" + T(E(entity.DisplayUrl)) + ""; } private static string FormatHashtagEntity(string targetText, TwitterEntityHashtag entity) - => "" + t(e(targetText)) + ""; + => "" + T(E(targetText)) + ""; private static string FormatMentionEntity(string targetText, TwitterEntityMention entity) - => "" + t(e(targetText)) + ""; + => "" + T(E(targetText)) + ""; private static string FormatEmojiEntity(string targetText, TwitterEntityEmoji entity) { if (!SettingManager.Local.UseTwemoji) - return t(e(targetText)); + return T(E(targetText)); if (MyCommon.IsNullOrEmpty(entity.Url)) return ""; - return "\"""; + return "\"""; } // 長いのでエイリアスとして e(...), eu(...), t(...) でエスケープできるようにする - private static readonly Func e = EscapeHtml; - private static readonly Func eu = Uri.EscapeDataString; - private static readonly Func t = FilterText; + private static readonly Func E = EscapeHtml; + private static readonly Func EU = Uri.EscapeDataString; + private static readonly Func T = FilterText; private static string EscapeHtml(string text) { diff --git a/OpenTween/TweetThumbnail.Designer.cs b/OpenTween/TweetThumbnail.Designer.cs index 6e49c47ca..702d66159 100644 --- a/OpenTween/TweetThumbnail.Designer.cs +++ b/OpenTween/TweetThumbnail.Designer.cs @@ -49,7 +49,7 @@ private void InitializeComponent() this.scrollBar.Maximum = 0; this.scrollBar.Name = "scrollBar"; this.toolTip.SetToolTip(this.scrollBar, resources.GetString("scrollBar.ToolTip")); - this.scrollBar.ValueChanged += new System.EventHandler(this.scrollBar_ValueChanged); + this.scrollBar.ValueChanged += new System.EventHandler(this.ScrollBar_ValueChanged); // // panelPictureBox // @@ -68,19 +68,19 @@ private void InitializeComponent() this.searchImageSauceNaoMenuItem}); this.contextMenuStrip.Name = "contextMenuStrip"; this.toolTip.SetToolTip(this.contextMenuStrip, resources.GetString("contextMenuStrip.ToolTip")); - this.contextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip_Opening); + this.contextMenuStrip.Opening += new System.ComponentModel.CancelEventHandler(this.ContextMenuStrip_Opening); // // openMenuItem // resources.ApplyResources(this.openMenuItem, "openMenuItem"); this.openMenuItem.Name = "openMenuItem"; - this.openMenuItem.Click += new System.EventHandler(this.openMenuItem_Click); + this.openMenuItem.Click += new System.EventHandler(this.OpenMenuItem_Click); // // copyUrlMenuItem // resources.ApplyResources(this.copyUrlMenuItem, "copyUrlMenuItem"); this.copyUrlMenuItem.Name = "copyUrlMenuItem"; - this.copyUrlMenuItem.Click += new System.EventHandler(this.copyUrlMenuItem_Click); + this.copyUrlMenuItem.Click += new System.EventHandler(this.CopyUrlMenuItem_Click); // // toolStripSeparator1 // @@ -91,13 +91,13 @@ private void InitializeComponent() // resources.ApplyResources(this.searchImageGoogleMenuItem, "searchImageGoogleMenuItem"); this.searchImageGoogleMenuItem.Name = "searchImageGoogleMenuItem"; - this.searchImageGoogleMenuItem.Click += new System.EventHandler(this.searchSimilarImageMenuItem_Click); + this.searchImageGoogleMenuItem.Click += new System.EventHandler(this.SearchSimilarImageMenuItem_Click); // // searchImageSauceNaoMenuItem // resources.ApplyResources(this.searchImageSauceNaoMenuItem, "searchImageSauceNaoMenuItem"); this.searchImageSauceNaoMenuItem.Name = "searchImageSauceNaoMenuItem"; - this.searchImageSauceNaoMenuItem.Click += new System.EventHandler(this.searchImageSauceNaoMenuItem_Click); + this.searchImageSauceNaoMenuItem.Click += new System.EventHandler(this.SearchImageSauceNaoMenuItem_Click); // // TweetThumbnail // diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index 97a7d614a..4a7e48e6a 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -43,7 +43,7 @@ namespace OpenTween { public partial class TweetThumbnail : UserControl { - protected internal List pictureBox = new List(); + protected internal List PictureBox = new List(); protected MouseWheelMessageFilter filter = new MouseWheelMessageFilter(); public event EventHandler? ThumbnailLoading; @@ -51,7 +51,7 @@ public partial class TweetThumbnail : UserControl public event EventHandler? ThumbnailImageSearchClick; public ThumbnailInfo Thumbnail - => (ThumbnailInfo)this.pictureBox[this.scrollBar.Value].Tag; + => (ThumbnailInfo)this.PictureBox[this.scrollBar.Value].Tag; public TweetThumbnail() => this.InitializeComponent(); @@ -84,7 +84,7 @@ public async Task ShowThumbnailAsync(PostClass post, CancellationToken cancelTok for (var i = 0; i < thumbnails.Length; i++) { var thumb = thumbnails[i]; - var picbox = this.pictureBox[i]; + var picbox = this.PictureBox[i]; picbox.Tag = thumb; picbox.ContextMenuStrip = this.contextMenuStrip; @@ -128,20 +128,20 @@ protected virtual Task> GetThumbailInfoAsync(PostClas /// 表示するサムネイルの数 protected void SetThumbnailCount(int count) { - if (count == 0 && this.pictureBox.Count == 0) + if (count == 0 && this.PictureBox.Count == 0) return; using (ControlTransaction.Layout(this.panelPictureBox, false)) { this.panelPictureBox.Controls.Clear(); - foreach (var picbox in this.pictureBox) + foreach (var picbox in this.PictureBox) { var memoryImage = picbox.Image; this.filter.Unregister(picbox); - picbox.MouseWheel -= this.pictureBox_MouseWheel; - picbox.DoubleClick -= this.pictureBox_DoubleClick; + picbox.MouseWheel -= this.PictureBox_MouseWheel; + picbox.DoubleClick -= this.PictureBox_DoubleClick; picbox.Dispose(); memoryImage?.Dispose(); @@ -149,7 +149,7 @@ protected void SetThumbnailCount(int count) // メモリリーク対策 (http://stackoverflow.com/questions/2792427#2793714) picbox.ContextMenuStrip = null; } - this.pictureBox.Clear(); + this.PictureBox.Clear(); this.scrollBar.Maximum = (count > 0) ? count - 1 : 0; this.scrollBar.Value = 0; @@ -158,13 +158,13 @@ protected void SetThumbnailCount(int count) { var picbox = this.CreatePictureBox("pictureBox" + i); picbox.Visible = i == 0; - picbox.MouseWheel += this.pictureBox_MouseWheel; - picbox.DoubleClick += this.pictureBox_DoubleClick; + picbox.MouseWheel += this.PictureBox_MouseWheel; + picbox.DoubleClick += this.PictureBox_DoubleClick; this.filter.Register(picbox); this.panelPictureBox.Controls.Add(picbox); - this.pictureBox.Add(picbox); + this.PictureBox.Add(picbox); } } } @@ -211,19 +211,19 @@ protected override void ScaleControl(SizeF factor, BoundsSpecified specified) OTBaseForm.ScaleChildControl(this.scrollBar, factor); } - private void scrollBar_ValueChanged(object sender, EventArgs e) + private void ScrollBar_ValueChanged(object sender, EventArgs e) { using (ControlTransaction.Layout(this, false)) { var value = this.scrollBar.Value; - for (var i = 0; i < this.pictureBox.Count; i++) + for (var i = 0; i < this.PictureBox.Count; i++) { - this.pictureBox[i].Visible = i == value; + this.PictureBox[i].Visible = i == value; } } } - private void pictureBox_MouseWheel(object sender, MouseEventArgs e) + private void PictureBox_MouseWheel(object sender, MouseEventArgs e) { if (e.Delta > 0) this.ScrollUp(); @@ -231,13 +231,13 @@ private void pictureBox_MouseWheel(object sender, MouseEventArgs e) this.ScrollDown(); } - private void pictureBox_DoubleClick(object sender, EventArgs e) + private void PictureBox_DoubleClick(object sender, EventArgs e) { if (((PictureBox)sender).Tag is ThumbnailInfo thumb) this.OpenImage(thumb); } - private void contextMenuStrip_Opening(object sender, CancelEventArgs e) + private void ContextMenuStrip_Opening(object sender, CancelEventArgs e) { var picbox = (OTPictureBox)this.contextMenuStrip.SourceControl; var thumb = (ThumbnailInfo)picbox.Tag; @@ -257,7 +257,7 @@ private void contextMenuStrip_Opening(object sender, CancelEventArgs e) } } - private void searchSimilarImageMenuItem_Click(object sender, EventArgs e) + private void SearchSimilarImageMenuItem_Click(object sender, EventArgs e) { var searchTargetUri = (string)this.searchImageGoogleMenuItem.Tag; var searchUri = this.GetImageSearchUriGoogle(searchTargetUri); @@ -265,7 +265,7 @@ private void searchSimilarImageMenuItem_Click(object sender, EventArgs e) this.ThumbnailImageSearchClick?.Invoke(this, new ThumbnailImageSearchEventArgs(searchUri)); } - private void searchImageSauceNaoMenuItem_Click(object sender, EventArgs e) + private void SearchImageSauceNaoMenuItem_Click(object sender, EventArgs e) { var searchTargetUri = (string)this.searchImageSauceNaoMenuItem.Tag; var searchUri = this.GetImageSearchUriSauceNao(searchTargetUri); @@ -273,10 +273,10 @@ private void searchImageSauceNaoMenuItem_Click(object sender, EventArgs e) this.ThumbnailImageSearchClick?.Invoke(this, new ThumbnailImageSearchEventArgs(searchUri)); } - private void openMenuItem_Click(object sender, EventArgs e) + private void OpenMenuItem_Click(object sender, EventArgs e) => this.OpenImage(this.Thumbnail); - private void copyUrlMenuItem_Click(object sender, EventArgs e) + private void CopyUrlMenuItem_Click(object sender, EventArgs e) { try { diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index f2c31cdcf..17680f49b 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -81,37 +81,37 @@ public class Twitter : IDisposable private const string HASHTAG_TERMINATOR = "[^A-Za-z0-9_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; public const string HASHTAG = "(" + HASHTAG_BOUNDARY + ")(#|#)(" + HASHTAG_ALPHANUMERIC + "*" + HASHTAG_ALPHA + HASHTAG_ALPHANUMERIC + "*)(?=" + HASHTAG_TERMINATOR + "|" + HASHTAG_BOUNDARY + ")"; // URL正規表現 - private const string url_valid_preceding_chars = @"(?:[^A-Za-z0-9@@$##\ufffe\ufeff\uffff\u202a-\u202e]|^)"; - public const string url_invalid_without_protocol_preceding_chars = @"[-_./]$"; - private const string url_invalid_domain_chars = @"\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$\u2000-\u200a\u0009-\u000d\u0020\u0085\u00a0\u1680\u180e\u2028\u2029\u202f\u205f\u3000\ufffe\ufeff\uffff\u202a-\u202e"; - private const string url_valid_domain_chars = @"[^" + url_invalid_domain_chars + "]"; - private const string url_valid_subdomain = @"(?:(?:" + url_valid_domain_chars + @"(?:[_-]|" + url_valid_domain_chars + @")*)?" + url_valid_domain_chars + @"\.)"; - private const string url_valid_domain_name = @"(?:(?:" + url_valid_domain_chars + @"(?:-|" + url_valid_domain_chars + @")*)?" + url_valid_domain_chars + @"\.)"; - private const string url_valid_GTLD = @"(?:(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx)(?=[^0-9a-zA-Z]|$))"; - private const string url_valid_CCTLD = @"(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))"; - private const string url_valid_punycode = @"(?:xn--[0-9a-z]+)"; - private const string url_valid_domain = @"(?" + url_valid_subdomain + "*" + url_valid_domain_name + "(?:" + url_valid_GTLD + "|" + url_valid_CCTLD + ")|" + url_valid_punycode + ")"; - public const string url_valid_ascii_domain = @"(?:(?:[a-z0-9" + LATIN_ACCENTS + @"]+)\.)+(?:" + url_valid_GTLD + "|" + url_valid_CCTLD + "|" + url_valid_punycode + ")"; - public const string url_invalid_short_domain = "^" + url_valid_domain_name + url_valid_CCTLD + "$"; - private const string url_valid_port_number = @"[0-9]+"; - - private const string url_valid_general_path_chars = @"[a-z0-9!*';:=+,.$/%#\[\]\-_~|&" + LATIN_ACCENTS + "]"; - private const string url_balance_parens = @"(?:\(" + url_valid_general_path_chars + @"+\))"; - private const string url_valid_path_ending_chars = @"(?:[+\-a-z0-9=_#/" + LATIN_ACCENTS + "]|" + url_balance_parens + ")"; - private const string pth = "(?:" + + private const string UrlValidPrecedingChars = @"(?:[^A-Za-z0-9@@$##\ufffe\ufeff\uffff\u202a-\u202e]|^)"; + public const string UrlInvalidWithoutProtocolPrecedingChars = @"[-_./]$"; + private const string UrlInvalidDomainChars = @"\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$\u2000-\u200a\u0009-\u000d\u0020\u0085\u00a0\u1680\u180e\u2028\u2029\u202f\u205f\u3000\ufffe\ufeff\uffff\u202a-\u202e"; + private const string UrlValidDomainChars = @"[^" + UrlInvalidDomainChars + "]"; + private const string UrlValidSubdomain = @"(?:(?:" + UrlValidDomainChars + @"(?:[_-]|" + UrlValidDomainChars + @")*)?" + UrlValidDomainChars + @"\.)"; + private const string UrlValidDomainName = @"(?:(?:" + UrlValidDomainChars + @"(?:-|" + UrlValidDomainChars + @")*)?" + UrlValidDomainChars + @"\.)"; + private const string UrlValidGTLD = @"(?:(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx)(?=[^0-9a-zA-Z]|$))"; + private const string UrlValidCCTLD = @"(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))"; + private const string UrlValidPunycode = @"(?:xn--[0-9a-z]+)"; + private const string UrlValidDomain = @"(?" + UrlValidSubdomain + "*" + UrlValidDomainName + "(?:" + UrlValidGTLD + "|" + UrlValidCCTLD + ")|" + UrlValidPunycode + ")"; + public const string UrlValidAsciiDomain = @"(?:(?:[a-z0-9" + LATIN_ACCENTS + @"]+)\.)+(?:" + UrlValidGTLD + "|" + UrlValidCCTLD + "|" + UrlValidPunycode + ")"; + public const string UrlInvalidShortDomain = "^" + UrlValidDomainName + UrlValidCCTLD + "$"; + private const string UrlValidPortNumber = @"[0-9]+"; + + private const string UrlValidGeneralPathChars = @"[a-z0-9!*';:=+,.$/%#\[\]\-_~|&" + LATIN_ACCENTS + "]"; + private const string UrlBalanceParens = @"(?:\(" + UrlValidGeneralPathChars + @"+\))"; + private const string UrlValidPathEndingChars = @"(?:[+\-a-z0-9=_#/" + LATIN_ACCENTS + "]|" + UrlBalanceParens + ")"; + private const string Pth = "(?:" + "(?:" + - url_valid_general_path_chars + "*" + - "(?:" + url_balance_parens + url_valid_general_path_chars + "*)*" + - url_valid_path_ending_chars + - ")|(?:@" + url_valid_general_path_chars + "+/)" + + UrlValidGeneralPathChars + "*" + + "(?:" + UrlBalanceParens + UrlValidGeneralPathChars + "*)*" + + UrlValidPathEndingChars + + ")|(?:@" + UrlValidGeneralPathChars + "+/)" + ")"; - private const string qry = @"(?\?[a-z0-9!?*'();:&=+$/%#\[\]\-_.,~|]*[a-z0-9_&=#/])?"; - public const string rgUrl = @"(?" + url_valid_preceding_chars + ")" + + private const string Qry = @"(?\?[a-z0-9!?*'();:&=+$/%#\[\]\-_.,~|]*[a-z0-9_&=#/])?"; + public const string RgUrl = @"(?" + UrlValidPrecedingChars + ")" + "(?(?https?://)?" + - "(?" + url_valid_domain + ")" + - "(?::" + url_valid_port_number + ")?" + - "(?/" + pth + "*)?" + - qry + + "(?" + UrlValidDomain + ")" + + "(?::" + UrlValidPortNumber + ")?" + + "(?/" + Pth + "*)?" + + Qry + ")"; #endregion @@ -1361,7 +1361,7 @@ internal static string CreateAccessibleText(string text, TwitterEntities? entiti /// public async Task RefreshFollowerIds() { - if (MyCommon._endingFlag) return; + if (MyCommon.EndingFlag) return; var cursor = -1L; var newFollowerIds = Enumerable.Empty(); @@ -1389,7 +1389,7 @@ public async Task RefreshFollowerIds() /// public async Task RefreshNoRetweetIds() { - if (MyCommon._endingFlag) return; + if (MyCommon.EndingFlag) return; this.noRTId = await this.Api.NoRetweetIds() .ConfigureAwait(false); @@ -1596,7 +1596,7 @@ internal static (string SourceText, Uri? SourceUri) ParseSource(string? sourceHt { if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return null; - if (MyCommon._endingFlag) return null; + if (MyCommon.EndingFlag) return null; var limits = await this.Api.ApplicationRateLimitStatus() .ConfigureAwait(false); @@ -1612,7 +1612,7 @@ internal static (string SourceText, Uri? SourceUri) ParseSource(string? sourceHt /// public async Task RefreshBlockIds() { - if (MyCommon._endingFlag) return; + if (MyCommon.EndingFlag) return; var cursor = -1L; var newBlockIds = Enumerable.Empty(); @@ -1637,7 +1637,7 @@ public async Task RefreshBlockIds() /// public async Task RefreshMuteUserIdsAsync() { - if (MyCommon._endingFlag) return; + if (MyCommon.EndingFlag) return; var ids = await TwitterIds.GetAllItemsAsync(x => this.Api.MutesUsersIds(x)) .ConfigureAwait(false); diff --git a/OpenTween/UserInfo.cs b/OpenTween/UserInfo.cs index ad8d69f7b..689256a92 100644 --- a/OpenTween/UserInfo.cs +++ b/OpenTween/UserInfo.cs @@ -84,8 +84,6 @@ public UserInfo(TwitterUser user) public string RecentPost = ""; public DateTimeUtc PostCreatedAt; public string PostSource = ""; // html形式 "Tween" - public bool isFollowing = false; - public bool isFollowed = false; public override string ToString() => this.ScreenName + " / " + this.Name; diff --git a/OpenTween/UserInfoDialog.cs b/OpenTween/UserInfoDialog.cs index f6db1c495..0cdc1f608 100644 --- a/OpenTween/UserInfoDialog.cs +++ b/OpenTween/UserInfoDialog.cs @@ -178,7 +178,7 @@ private async Task SetDescriptionAsync(string? descriptionText, TwitterEntities? .Concat(TweetExtractor.ExtractEmojiEntities(descriptionText)); var html = TweetFormatter.AutoLinkHtml(descriptionText, mergedEntities); - html = this.mainForm.createDetailHtml(html); + html = this.mainForm.CreateDetailHtml(html); if (cancellationToken.IsCancellationRequested) return; @@ -257,7 +257,7 @@ private async Task SetRecentStatusAsync(TwitterStatus? status, CancellationToken var mergedEntities = entities.Concat(TweetExtractor.ExtractEmojiEntities(status.FullText)); var html = TweetFormatter.AutoLinkHtml(status.FullText, mergedEntities); - html = this.mainForm.createDetailHtml(html + + html = this.mainForm.CreateDetailHtml(html + " Posted at " + MyCommon.DateTimeParse(status.CreatedAt).ToLocalTimeString() + " via " + status.Source); From 76bc622695a99b298bd6eee7aa17f0986e4774db Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 05:32:14 +0900 Subject: [PATCH 101/402] =?UTF-8?q?=E8=AD=98=E5=88=A5=E5=AD=90=E3=82=92cam?= =?UTF-8?q?elCase=E3=81=AB=E3=81=99=E3=82=8B=20(SA1306,=20SA1309,=20SA1312?= =?UTF-8?q?,=20SA1313)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/HttpMessageHandlerMock.cs | 10 +- OpenTween.Tests/Models/PostClassTest.cs | 12 +- OpenTween.Tests/Models/TabInformationTest.cs | 2 +- .../Thumbnail/Services/ImgAzyobuziNetTest.cs | 4 +- OpenTween/ApiInfoDialog.cs | 6 +- OpenTween/AsyncTimer.cs | 2 +- OpenTween/AtIdSupplement.cs | 6 +- OpenTween/FilterDialog.cs | 62 +- OpenTween/Growl.cs | 104 +- OpenTween/HashtagManage.cs | 28 +- OpenTween/HookGlobalHotkey.cs | 40 +- OpenTween/ListElement.cs | 16 +- OpenTween/ListManage.cs | 4 +- OpenTween/MediaItem.cs | 24 +- OpenTween/Models/FilterTabModel.cs | 20 +- OpenTween/Models/PostClass.cs | 78 +- OpenTween/Models/PostFilterRule.cs | 134 +- OpenTween/Models/PublicSearchTabModel.cs | 12 +- OpenTween/Models/RelatedPostsTabModel.cs | 2 +- OpenTween/Models/TabInformations.cs | 142 +- OpenTween/Models/TabModel.cs | 26 +- OpenTween/MyCommon.cs | 42 +- OpenTween/OTSplitContainer.cs | 8 +- OpenTween/OpenURL.cs | 24 +- OpenTween/SendErrorReportForm.cs | 30 +- OpenTween/Setting/SettingBase.cs | 18 +- OpenTween/TabsDialog.cs | 12 +- .../Thumbnail/Services/ImgAzyobuziNet.cs | 52 +- .../Services/MetaThumbnailService.cs | 8 +- OpenTween/ToolStripAPIGauge.cs | 50 +- OpenTween/ToolStripLabelHistory.cs | 12 +- OpenTween/Tween.cs | 1900 ++++++++--------- OpenTween/TweetDetailsView.cs | 42 +- OpenTween/Twitter.cs | 36 +- OpenTween/UserInfoDialog.cs | 50 +- OpenTween/WebBrowserController.cs | 8 +- 36 files changed, 1513 insertions(+), 1513 deletions(-) diff --git a/OpenTween.Tests/HttpMessageHandlerMock.cs b/OpenTween.Tests/HttpMessageHandlerMock.cs index feb8ae568..bfa72e974 100644 --- a/OpenTween.Tests/HttpMessageHandlerMock.cs +++ b/OpenTween.Tests/HttpMessageHandlerMock.cs @@ -31,21 +31,21 @@ namespace OpenTween { public class HttpMessageHandlerMock : HttpMessageHandler { - private readonly Queue>> Queue = + private readonly Queue>> queue = new Queue>>(); public int QueueCount - => this.Queue.Count; + => this.queue.Count; public void Enqueue(Func> handler) - => this.Queue.Enqueue(handler); + => this.queue.Enqueue(handler); public void Enqueue(Func handler) - => this.Queue.Enqueue(x => Task.Run(() => handler(x))); + => this.queue.Enqueue(x => Task.Run(() => handler(x))); protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - var handler = this.Queue.Dequeue(); + var handler = this.queue.Dequeue(); return await handler(request); } } diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index 94bf93d0d..4ecbaf303 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -63,11 +63,11 @@ protected override PostClass RetweetSource } } - private PostClassGroup PostGroup; + private PostClassGroup postGroup; public PostClassTest() { - this.PostGroup = new PostClassGroup( + this.postGroup = new PostClassGroup( new TestPostClass { StatusId = 1L }, new TestPostClass { StatusId = 2L, IsFav = true }, new TestPostClass { StatusId = 3L, IsFav = false, RetweetedId = 2L }); @@ -97,7 +97,7 @@ public void TextSingleLineTest(string text, string expected) [InlineData(2L, true)] [InlineData(3L, true)] public void GetIsFavTest(long statusId, bool expected) - => Assert.Equal(expected, this.PostGroup[statusId].IsFav); + => Assert.Equal(expected, this.postGroup[statusId].IsFav); [Theory] [InlineData(2L, true)] @@ -106,13 +106,13 @@ public void GetIsFavTest(long statusId, bool expected) [InlineData(3L, false)] public void SetIsFavTest(long statusId, bool isFav) { - var post = this.PostGroup[statusId]; + var post = this.postGroup[statusId]; post.IsFav = isFav; Assert.Equal(isFav, post.IsFav); if (post.RetweetedId != null) - Assert.Equal(isFav, this.PostGroup[post.RetweetedId.Value].IsFav); + Assert.Equal(isFav, this.postGroup[post.RetweetedId.Value].IsFav); } #pragma warning disable SA1008 // Opening parenthesis should be spaced correctly @@ -407,7 +407,7 @@ public FakeExpandedUrlInfo(string url, string expandedUrl, bool deepExpand) } protected override async Task DeepExpandAsync() - => this._expandedUrl = await this.FakeResult.Task; + => this.expandedUrl = await this.FakeResult.Task; } [Fact] diff --git a/OpenTween.Tests/Models/TabInformationTest.cs b/OpenTween.Tests/Models/TabInformationTest.cs index 63142f26c..380305c6c 100644 --- a/OpenTween.Tests/Models/TabInformationTest.cs +++ b/OpenTween.Tests/Models/TabInformationTest.cs @@ -836,7 +836,7 @@ public static PostFilterRule Create(Func filterDe { return new TestPostFilterRule { - FilterDelegate = filterDelegate, + filterDelegate = filterDelegate, IsDirty = false, }; } diff --git a/OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs b/OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs index 76cec5c45..a29364ad2 100644 --- a/OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs @@ -47,12 +47,12 @@ public TestImgAzyobuziNet() public TestImgAzyobuziNet(string[] apiHosts) : base(null, autoupdate: false) { - this.ApiHosts = apiHosts; + this.apiHosts = apiHosts; this.LoadRegexAsync().Wait(); } public string? GetApiBase() - => this.ApiBase; + => this.apiBase; protected override Task FetchRegexAsync(string apiBase) { diff --git a/OpenTween/ApiInfoDialog.cs b/OpenTween/ApiInfoDialog.cs index 2ca64eab2..05c10bd64 100644 --- a/OpenTween/ApiInfoDialog.cs +++ b/OpenTween/ApiInfoDialog.cs @@ -39,7 +39,7 @@ public partial class ApiInfoDialog : OTBaseForm public ApiInfoDialog() => this.InitializeComponent(); - private readonly List _tlEndpoints = new List + private readonly List tlEndpoints = new List { "/statuses/home_timeline", "/statuses/mentions_timeline", @@ -57,7 +57,7 @@ private void ApiInfoDialog_Shown(object sender, EventArgs e) { // TL更新用エンドポイントの追加 var group = this.ListViewApi.Groups[0]; - foreach (var endpoint in this._tlEndpoints) + foreach (var endpoint in this.tlEndpoints) { var apiLimit = MyCommon.TwitterApiInfo.AccessLimit[endpoint]; if (apiLimit == null) @@ -68,7 +68,7 @@ private void ApiInfoDialog_Shown(object sender, EventArgs e) // その他 group = this.ListViewApi.Groups[1]; - var apiStatuses = MyCommon.TwitterApiInfo.AccessLimit.Where(x => !this._tlEndpoints.Contains(x.Key)).OrderBy(x => x.Key); + var apiStatuses = MyCommon.TwitterApiInfo.AccessLimit.Where(x => !this.tlEndpoints.Contains(x.Key)).OrderBy(x => x.Key); foreach (var (endpoint, apiLimit) in apiStatuses) { this.AddListViewItem(endpoint, apiLimit, group); diff --git a/OpenTween/AsyncTimer.cs b/OpenTween/AsyncTimer.cs index 2b9ddb665..4e3c97b87 100644 --- a/OpenTween/AsyncTimer.cs +++ b/OpenTween/AsyncTimer.cs @@ -43,7 +43,7 @@ public AsyncTimer(Func callback) this.timer = new Timer(this.TimerCallback); } - private async void TimerCallback(object _) + private async void TimerCallback(object state) { try { diff --git a/OpenTween/AtIdSupplement.cs b/OpenTween/AtIdSupplement.cs index 282581171..dd4456138 100644 --- a/OpenTween/AtIdSupplement.cs +++ b/OpenTween/AtIdSupplement.cs @@ -137,13 +137,13 @@ private void AtIdSupplement_Shown(object sender, EventArgs e) public AtIdSupplement() => this.InitializeComponent(); - public AtIdSupplement(List ItemList, string startCharacter) + public AtIdSupplement(List itemList, string startCharacter) { this.InitializeComponent(); - for (var i = 0; i < ItemList.Count; ++i) + for (var i = 0; i < itemList.Count; ++i) { - this.TextId.AutoCompleteCustomSource.Add(ItemList[i]); + this.TextId.AutoCompleteCustomSource.Add(itemList[i]); } this.startChar = startCharacter; } diff --git a/OpenTween/FilterDialog.cs b/OpenTween/FilterDialog.cs index 3f10a8f49..d0d98897f 100644 --- a/OpenTween/FilterDialog.cs +++ b/OpenTween/FilterDialog.cs @@ -44,10 +44,10 @@ namespace OpenTween { public partial class FilterDialog : OTBaseForm { - private EDITMODE _mode; - private bool _directAdd; - private MultiSelectionState _multiSelState = MultiSelectionState.None; - private readonly TabInformations _sts; + private EDITMODE mode; + private bool directAdd; + private MultiSelectionState multiSelState = MultiSelectionState.None; + private readonly TabInformations sts; private List tabs = new List(); private int selectedTabIndex = -1; @@ -78,10 +78,10 @@ private enum MultiSelectionState private EnableButtonMode RuleEnableButtonMode { - get => this._ruleEnableButtonMode; + get => this.ruleEnableButtonMode; set { - this._ruleEnableButtonMode = value; + this.ruleEnableButtonMode = value; this.buttonRuleToggleEnabled.Text = value == FilterDialog.EnableButtonMode.Enable ? Properties.Resources.EnableButtonCaption @@ -89,7 +89,7 @@ private EnableButtonMode RuleEnableButtonMode this.buttonRuleToggleEnabled.Enabled = value != EnableButtonMode.NotSelected; } } - private EnableButtonMode _ruleEnableButtonMode = FilterDialog.EnableButtonMode.NotSelected; + private EnableButtonMode ruleEnableButtonMode = FilterDialog.EnableButtonMode.NotSelected; public TabModel? SelectedTab => this.selectedTabIndex != -1 ? this.tabs[this.selectedTabIndex] : null; @@ -98,13 +98,13 @@ public FilterDialog() { this.InitializeComponent(); - this._sts = TabInformations.GetInstance(); + this.sts = TabInformations.GetInstance(); this.RefreshListTabs(); } private void RefreshListTabs() { - this.tabs = this._sts.Tabs.Append(this._sts.MuteTab).ToList(); + this.tabs = this.sts.Tabs.Append(this.sts.MuteTab).ToList(); using (ControlTransaction.Update(this.ListTabs)) { @@ -152,7 +152,7 @@ private void SetFilters(TabModel tab) if (idx == -1) idx = 0; this.ComboSound.SelectedIndex = idx; - if (this._directAdd) return; + if (this.directAdd) return; if (tab.TabType == MyCommon.TabUsageType.Mute) { @@ -308,8 +308,8 @@ public void AddNewFilter(string id, string msg) this.OptCopy.Checked = true; this.CheckMark.Checked = true; this.UID.Focus(); - this._mode = EDITMODE.AddNew; - this._directAdd = true; + this.mode = EDITMODE.AddNew; + this.directAdd = true; } private void ButtonNew_Click(object sender, EventArgs e) @@ -362,7 +362,7 @@ private void ButtonNew_Click(object sender, EventArgs e) this.OptCopy.Checked = true; this.CheckMark.Checked = true; this.UID.Focus(); - this._mode = EDITMODE.AddNew; + this.mode = EDITMODE.AddNew; } private void ButtonEdit_Click(object sender, EventArgs e) @@ -389,7 +389,7 @@ private void ButtonEdit_Click(object sender, EventArgs e) this.ListTabs.Enabled = false; this.GroupTab.Enabled = false; - this._mode = EDITMODE.Edit; + this.mode = EDITMODE.Edit; } private void ButtonDelete_Click(object sender, EventArgs e) @@ -457,7 +457,7 @@ private void ButtonCancel_Click(object sender, EventArgs e) this.buttonRuleToggleEnabled.Enabled = false; } this.ButtonClose.Enabled = true; - if (this._directAdd) + if (this.directAdd) { this.Close(); } @@ -465,7 +465,7 @@ private void ButtonCancel_Click(object sender, EventArgs e) private void ShowDetail() { - if (this._directAdd) return; + if (this.directAdd) return; if (this.ListFilters.SelectedIndex > -1) { @@ -622,7 +622,7 @@ private void ButtonOK_Click(object sender, EventArgs e) var i = this.ListFilters.SelectedIndex; PostFilterRule ft; - if (this._mode == EDITMODE.AddNew) + if (this.mode == EDITMODE.AddNew) ft = new PostFilterRule(); else ft = (PostFilterRule)this.ListFilters.SelectedItem; @@ -709,7 +709,7 @@ private void ButtonOK_Click(object sender, EventArgs e) ft.ExFilterRt = this.CheckExRetweet.Checked; ft.ExUseLambda = this.CheckExLambDa.Checked; - if (this._mode == EDITMODE.AddNew) + if (this.mode == EDITMODE.AddNew) { if (!tab.AddFilter(ft)) MessageBox.Show(Properties.Resources.ButtonOK_ClickText4, Properties.Resources.ButtonOK_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -717,7 +717,7 @@ private void ButtonOK_Click(object sender, EventArgs e) this.SetFilters(tab); this.ListFilters.SelectedIndex = -1; - if (this._mode == EDITMODE.AddNew) + if (this.mode == EDITMODE.AddNew) { this.ListFilters.SelectedIndex = this.ListFilters.Items.Count - 1; } @@ -725,9 +725,9 @@ private void ButtonOK_Click(object sender, EventArgs e) { this.ListFilters.SelectedIndex = i; } - this._mode = EDITMODE.None; + this.mode = EDITMODE.None; - if (this._directAdd) + if (this.directAdd) { this.Close(); } @@ -867,7 +867,7 @@ private bool CheckExcludeRule(out bool isBlank) private void ListFilters_SelectedIndexChanged(object sender, EventArgs e) { - if (this._multiSelState != MultiSelectionState.None) // 複数選択処理中は無視する + if (this.multiSelState != MultiSelectionState.None) // 複数選択処理中は無視する return; this.ShowDetail(); @@ -892,7 +892,7 @@ private void ButtonClose_Click(object sender, EventArgs e) => this.Close(); private void FilterDialog_FormClosed(object sender, FormClosedEventArgs e) - => this._directAdd = false; + => this.directAdd = false; private void FilterDialog_KeyDown(object sender, KeyEventArgs e) { @@ -964,7 +964,7 @@ private async void ButtonAddTab_Click(object sender, EventArgs e) MyCommon.TabUsageType tabType; using (var inputName = new InputTabName()) { - inputName.TabName = this._sts.MakeTabName("MyTab"); + inputName.TabName = this.sts.MakeTabName("MyTab"); inputName.IsShowUsage = true; inputName.ShowDialog(); if (inputName.DialogResult == DialogResult.Cancel) return; @@ -1018,7 +1018,7 @@ private async void ButtonAddTab_Click(object sender, EventArgs e) return; } - if (!this._sts.AddTab(tab) || !((TweenMain)this.Owner).AddNewTab(tab, startup: false)) + if (!this.sts.AddTab(tab) || !((TweenMain)this.Owner).AddNewTab(tab, startup: false)) { var tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName); MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); @@ -1190,7 +1190,7 @@ private void MoveSelectedRules(bool up) try { - this._multiSelState |= MultiSelectionState.MoveSelected; + this.multiSelState |= MultiSelectionState.MoveSelected; using (ControlTransaction.Update(this.ListFilters)) { @@ -1219,7 +1219,7 @@ private void MoveSelectedRules(bool up) } finally { - this._multiSelState &= ~MultiSelectionState.MoveSelected; + this.multiSelState &= ~MultiSelectionState.MoveSelected; } } @@ -1251,7 +1251,7 @@ private void ButtonRuleCopy_Click(object sender, EventArgs e) if (selectedTab != null && this.ListFilters.SelectedItem != null) { TabModel[] destinationTabs; - using (var dialog = new TabsDialog(this._sts)) + using (var dialog = new TabsDialog(this.sts)) { dialog.MultiSelect = true; dialog.Text = Properties.Resources.ButtonRuleCopy_ClickText1; @@ -1288,7 +1288,7 @@ private void ButtonRuleMove_Click(object sender, EventArgs e) if (selectedTab != null && this.ListFilters.SelectedItem != null) { TabModel[] destinationTabs; - using (var dialog = new TabsDialog(this._sts)) + using (var dialog = new TabsDialog(this.sts)) { dialog.MultiSelect = true; dialog.Text = Properties.Resources.ButtonRuleMove_ClickText1; @@ -1417,7 +1417,7 @@ private void ListFilters_KeyDown(object sender, KeyEventArgs e) { try { - this._multiSelState |= MultiSelectionState.SelectAll; + this.multiSelState |= MultiSelectionState.SelectAll; for (var i = 1; i < itemCount; i++) { @@ -1426,7 +1426,7 @@ private void ListFilters_KeyDown(object sender, KeyEventArgs e) } finally { - this._multiSelState &= ~MultiSelectionState.SelectAll; + this.multiSelState &= ~MultiSelectionState.SelectAll; } } diff --git a/OpenTween/Growl.cs b/OpenTween/Growl.cs index 8c827e212..e4f0b45d7 100644 --- a/OpenTween/Growl.cs +++ b/OpenTween/Growl.cs @@ -43,16 +43,16 @@ namespace OpenTween { public class GrowlHelper { - private Assembly? _connector = null; - private Assembly? _core = null; + private Assembly? connector = null; + private Assembly? core = null; - private object? _growlNTreply; - private object? _growlNTdm; - private object? _growlNTnew; - private object? _growlApp; + private object? growlNTreply; + private object? growlNTdm; + private object? growlNTnew; + private object? growlApp; - private object? _targetConnector; - bool _initialized = false; + private object? targetConnector; + private bool initialized = false; public class NotifyCallbackEventArgs : EventArgs { @@ -86,7 +86,7 @@ public bool IsAvailable { get { - if (this._connector == null || this._core == null || !this._initialized) + if (this.connector == null || this.core == null || !this.initialized) return false; else return true; @@ -123,7 +123,7 @@ public static bool IsDllExists public bool RegisterGrowl() { - this._initialized = false; + this.initialized = false; var dir = Application.StartupPath; var connectorPath = Path.Combine(dir, "Growl.Connector.dll"); var corePath = Path.Combine(dir, "Growl.CoreLibrary.dll"); @@ -131,8 +131,8 @@ public bool RegisterGrowl() try { if (!IsDllExists) return false; - this._connector = Assembly.LoadFile(connectorPath); - this._core = Assembly.LoadFile(corePath); + this.connector = Assembly.LoadFile(connectorPath); + this.core = Assembly.LoadFile(corePath); } catch (Exception) { @@ -141,10 +141,10 @@ public bool RegisterGrowl() try { - this._targetConnector = this._connector.CreateInstance("Growl.Connector.GrowlConnector"); - var _t = this._connector.GetType("Growl.Connector.NotificationType"); + this.targetConnector = this.connector.CreateInstance("Growl.Connector.GrowlConnector"); + var t = this.connector.GetType("Growl.Connector.NotificationType"); - this._growlNTreply = _t.InvokeMember( + this.growlNTreply = t.InvokeMember( null, BindingFlags.CreateInstance, null, @@ -152,14 +152,14 @@ public bool RegisterGrowl() new object[] { "REPLY", "Reply" }, CultureInfo.InvariantCulture); - this._growlNTdm = _t.InvokeMember(null, + this.growlNTdm = t.InvokeMember(null, BindingFlags.CreateInstance, null, null, new object[] { "DIRECT_MESSAGE", "DirectMessage" }, CultureInfo.InvariantCulture); - this._growlNTnew = _t.InvokeMember( + this.growlNTnew = t.InvokeMember( null, BindingFlags.CreateInstance, null, @@ -168,32 +168,32 @@ public bool RegisterGrowl() CultureInfo.InvariantCulture); var encryptType = - this._connector.GetType("Growl.Connector.Cryptography+SymmetricAlgorithmType").InvokeMember( + this.connector.GetType("Growl.Connector.Cryptography+SymmetricAlgorithmType").InvokeMember( "PlainText", BindingFlags.GetField, null, null, null, CultureInfo.InvariantCulture); - this._targetConnector.GetType().InvokeMember("EncryptionAlgorithm", BindingFlags.SetProperty, null, this._targetConnector, new object[] { encryptType }, CultureInfo.InvariantCulture); + this.targetConnector.GetType().InvokeMember("EncryptionAlgorithm", BindingFlags.SetProperty, null, this.targetConnector, new object[] { encryptType }, CultureInfo.InvariantCulture); - this._growlApp = this._connector.CreateInstance( + this.growlApp = this.connector.CreateInstance( "Growl.Connector.Application", false, BindingFlags.Default, null, new object[] { this.AppName }, null, null); if (File.Exists(Path.Combine(Application.StartupPath, "Icons\\Tween.png"))) { // Icons\Tween.pngを使用 - var ci = this._core.GetType("Growl.CoreLibrary.Resource").GetConstructor( + var ci = this.core.GetType("Growl.CoreLibrary.Resource").GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { typeof(string) }, null); var data = ci.Invoke(new object[] { Path.Combine(Application.StartupPath, "Icons\\Tween.png") }); - var pi = this._growlApp.GetType().GetProperty("Icon"); - pi.SetValue(this._growlApp, data, null); + var pi = this.growlApp.GetType().GetProperty("Icon"); + pi.SetValue(this.growlApp, data, null); } else if (File.Exists(Path.Combine(Application.StartupPath, "Icons\\MIcon.ico"))) { // アイコンセットにMIcon.icoが存在する場合それを使用 - var cibd = this._core.GetType("Growl.CoreLibrary.BinaryData").GetConstructor( + var cibd = this.core.GetType("Growl.CoreLibrary.BinaryData").GetConstructor( BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(byte[]) }, @@ -201,20 +201,20 @@ public bool RegisterGrowl() var bdata = cibd.Invoke( new object[] { this.IconToByteArray(Path.Combine(Application.StartupPath, "Icons\\MIcon.ico")) }); - var ciRes = this._core.GetType("Growl.CoreLibrary.Resource").GetConstructor( + var ciRes = this.core.GetType("Growl.CoreLibrary.Resource").GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { bdata.GetType() }, null); var data = ciRes.Invoke(new object[] { bdata }); - var pi = this._growlApp.GetType().GetProperty("Icon"); - pi.SetValue(this._growlApp, data, null); + var pi = this.growlApp.GetType().GetProperty("Icon"); + pi.SetValue(this.growlApp, data, null); } else { // 内蔵アイコンリソースを使用 - var cibd = this._core.GetType("Growl.CoreLibrary.BinaryData").GetConstructor( + var cibd = this.core.GetType("Growl.CoreLibrary.BinaryData").GetConstructor( BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(byte[]) }, @@ -222,45 +222,45 @@ public bool RegisterGrowl() var bdata = cibd.Invoke( new object[] { this.IconToByteArray(Properties.Resources.MIcon) }); - var ciRes = this._core.GetType("Growl.CoreLibrary.Resource").GetConstructor( + var ciRes = this.core.GetType("Growl.CoreLibrary.Resource").GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new Type[] { bdata.GetType() }, null); var data = ciRes.Invoke(new object[] { bdata }); - var pi = this._growlApp.GetType().GetProperty("Icon"); - pi.SetValue(this._growlApp, data, null); + var pi = this.growlApp.GetType().GetProperty("Icon"); + pi.SetValue(this.growlApp, data, null); } - var mi = this._targetConnector.GetType().GetMethod("Register", new Type[] { this._growlApp.GetType(), this._connector.GetType("Growl.Connector.NotificationType[]") }); + var mi = this.targetConnector.GetType().GetMethod("Register", new Type[] { this.growlApp.GetType(), this.connector.GetType("Growl.Connector.NotificationType[]") }); - _t = this._connector.GetType("Growl.Connector.NotificationType"); + t = this.connector.GetType("Growl.Connector.NotificationType"); var arglist = new ArrayList { - this._growlNTreply, - this._growlNTdm, - this._growlNTnew, + this.growlNTreply, + this.growlNTdm, + this.growlNTnew, }; - mi.Invoke(this._targetConnector, new object[] { this._growlApp, arglist.ToArray(_t) }); + mi.Invoke(this.targetConnector, new object[] { this.growlApp, arglist.ToArray(t) }); // コールバックメソッドの登録 - var tGrowlConnector = this._connector.GetType("Growl.Connector.GrowlConnector"); + var tGrowlConnector = this.connector.GetType("Growl.Connector.GrowlConnector"); var evNotificationCallback = tGrowlConnector.GetEvent("NotificationCallback"); var tDelegate = evNotificationCallback.EventHandlerType; var miHandler = typeof(GrowlHelper).GetMethod("GrowlCallbackHandler", BindingFlags.NonPublic | BindingFlags.Instance); var d = Delegate.CreateDelegate(tDelegate, this, miHandler); var miAddHandler = evNotificationCallback.GetAddMethod(); object[] addHandlerArgs = { d }; - miAddHandler.Invoke(this._targetConnector, addHandlerArgs); + miAddHandler.Invoke(this.targetConnector, addHandlerArgs); - this._initialized = true; + this.initialized = true; } catch (Exception) { - this._initialized = false; + this.initialized = false; return false; } @@ -269,7 +269,7 @@ public bool RegisterGrowl() public void Notify(NotifyType notificationType, string id, string title, string text, Image? icon = null, string url = "") { - if (!this._initialized) return; + if (!this.initialized) return; var notificationName = notificationType switch { @@ -282,7 +282,7 @@ public void Notify(NotifyType notificationType, string id, string title, string object? n; if (icon != null || !MyCommon.IsNullOrEmpty(url)) { - var gCore = this._core!.GetType("Growl.CoreLibrary.Resource"); + var gCore = this.core!.GetType("Growl.CoreLibrary.Resource"); object? res; if (icon != null) { @@ -303,13 +303,13 @@ public void Notify(NotifyType notificationType, string id, string title, string CultureInfo.InvariantCulture); } var priority = - this._connector!.GetType("Growl.Connector.Priority").InvokeMember( + this.connector!.GetType("Growl.Connector.Priority").InvokeMember( "Normal", BindingFlags.GetField, null, null, null, CultureInfo.InvariantCulture); - n = this._connector!.GetType("Growl.Connector.Notification").InvokeMember( + n = this.connector!.GetType("Growl.Connector.Notification").InvokeMember( "Notification", BindingFlags.CreateInstance, null, - this._connector, + this.connector, new object[] { this.AppName, @@ -326,11 +326,11 @@ public void Notify(NotifyType notificationType, string id, string title, string } else { - n = this._connector!.GetType("Growl.Connector.Notification").InvokeMember( + n = this.connector!.GetType("Growl.Connector.Notification").InvokeMember( "Notification", BindingFlags.CreateInstance, null, - this._connector, + this.connector, new object[] { this.AppName, @@ -341,14 +341,14 @@ public void Notify(NotifyType notificationType, string id, string title, string }, CultureInfo.InvariantCulture); } - var cc = this._connector.GetType("Growl.Connector.CallbackContext").InvokeMember( + var cc = this.connector.GetType("Growl.Connector.CallbackContext").InvokeMember( null, BindingFlags.CreateInstance, null, - this._connector, + this.connector, new object[] { "some fake information", notificationName }, CultureInfo.InvariantCulture); - this._targetConnector!.GetType().InvokeMember("Notify", BindingFlags.InvokeMethod, null, this._targetConnector, new object[] { n, cc }, CultureInfo.InvariantCulture); + this.targetConnector!.GetType().InvokeMember("Notify", BindingFlags.InvokeMethod, null, this.targetConnector, new object[] { n, cc }, CultureInfo.InvariantCulture); } private void GrowlCallbackHandler(object response, object callbackData, object state) @@ -357,7 +357,7 @@ private void GrowlCallbackHandler(object response, object callbackData, object s { // 定数取得 var vCLICK = - this._core!.GetType("Growl.CoreLibrary.CallbackResult").GetField( + this.core!.GetType("Growl.CoreLibrary.CallbackResult").GetField( "CLICK", BindingFlags.Public | BindingFlags.Static).GetRawConstantValue(); // 実際の値 diff --git a/OpenTween/HashtagManage.cs b/OpenTween/HashtagManage.cs index bb12db0a2..f09032cf9 100644 --- a/OpenTween/HashtagManage.cs +++ b/OpenTween/HashtagManage.cs @@ -51,10 +51,10 @@ public partial class HashtagManage : OTBaseForm public bool RunSilent { get; set; } // 入力補助画面 - private readonly AtIdSupplement _hashSupl; + private readonly AtIdSupplement hashSupl; // 編集モード - private bool _isAdd = false; + private bool isAdd = false; private void ChangeMode(bool isEdit) { @@ -77,7 +77,7 @@ private void AddButton_Click(object sender, EventArgs e) { this.UseHashText.Text = ""; this.ChangeMode(true); - this._isAdd = true; + this.isAdd = true; } private void EditButton_Click(object sender, EventArgs e) @@ -85,7 +85,7 @@ private void EditButton_Click(object sender, EventArgs e) if (this.HistoryHashList.SelectedIndices.Count == 0) return; this.UseHashText.Text = this.HistoryHashList.SelectedItems[0].ToString(); this.ChangeMode(true); - this._isAdd = false; + this.isAdd = false; } private void DeleteButton_Click(object sender, EventArgs e) @@ -211,27 +211,27 @@ private void HashtagManage_Shown(object sender, EventArgs e) this.ChangeMode(false); } - public HashtagManage(AtIdSupplement hashSuplForm, string[] history, string permanentHash, bool IsPermanent, bool IsHead, bool IsNotAddToAtReply) + public HashtagManage(AtIdSupplement hashSuplForm, string[] history, string permanentHash, bool isPermanent, bool isHead, bool isNotAddToAtReply) { // この呼び出しは、Windows フォーム デザイナで必要です。 this.InitializeComponent(); // InitializeComponent() 呼び出しの後で初期化を追加します。 - this._hashSupl = hashSuplForm; + this.hashSupl = hashSuplForm; this.HistoryHashList.Items.AddRange(history); this.UseHash = permanentHash; - this.IsPermanent = IsPermanent; - this.IsHead = IsHead; - this.IsNotAddToAtReply = IsNotAddToAtReply; + this.IsPermanent = isPermanent; + this.IsHead = isHead; + this.IsNotAddToAtReply = isNotAddToAtReply; } private void UseHashText_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == '#') { - this._hashSupl.ShowDialog(); - if (!MyCommon.IsNullOrEmpty(this._hashSupl.InputText)) + this.hashSupl.ShowDialog(); + if (!MyCommon.IsNullOrEmpty(this.hashSupl.InputText)) { var fHalf = ""; var eHalf = ""; @@ -244,8 +244,8 @@ private void UseHashText_KeyPress(object sender, KeyPressEventArgs e) { eHalf = this.UseHashText.Text.Substring(selStart); } - this.UseHashText.Text = fHalf + this._hashSupl.InputText + eHalf; - this.UseHashText.SelectionStart = selStart + this._hashSupl.InputText.Length; + this.UseHashText.Text = fHalf + this.hashSupl.InputText + eHalf; + this.UseHashText.SelectionStart = selStart + this.hashSupl.InputText.Length; } e.Handled = true; } @@ -298,7 +298,7 @@ private void PermOK_Button_Click(object sender, EventArgs e) if (!this.AdjustHashtags(ref hashStr, !this.RunSilent)) return; this.UseHashText.Text = hashStr; - if (!this._isAdd && this.HistoryHashList.SelectedIndices.Count > 0) + if (!this.isAdd && this.HistoryHashList.SelectedIndices.Count > 0) { var idx = this.HistoryHashList.SelectedIndices[0]; this.HistoryHashList.Items.RemoveAt(idx); diff --git a/OpenTween/HookGlobalHotkey.cs b/OpenTween/HookGlobalHotkey.cs index 74ce48f61..b29d4fc49 100644 --- a/OpenTween/HookGlobalHotkey.cs +++ b/OpenTween/HookGlobalHotkey.cs @@ -36,20 +36,20 @@ namespace OpenTween { public class HookGlobalHotkey : NativeWindow, IDisposable { - private readonly Form _targetForm; + private readonly Form targetForm; private class KeyEventValue { public KeyEventArgs KeyEvent { get; } public int Value { get; } - public KeyEventValue(KeyEventArgs keyEvent, int Value) + public KeyEventValue(KeyEventArgs keyEvent, int value) { this.KeyEvent = keyEvent; - this.Value = Value; + this.Value = value; } } - private readonly Dictionary _hotkeyID; + private readonly Dictionary hotkeyID; [Flags] public enum ModKeys @@ -68,9 +68,9 @@ protected override void WndProc(ref Message m) const int WM_HOTKEY = 0x312; if (m.Msg == WM_HOTKEY) { - if (this._hotkeyID.ContainsKey(m.WParam.ToInt32())) + if (this.hotkeyID.ContainsKey(m.WParam.ToInt32())) { - this.HotkeyPressed?.Invoke(this, this._hotkeyID[m.WParam.ToInt32()].KeyEvent); + this.HotkeyPressed?.Invoke(this, this.hotkeyID[m.WParam.ToInt32()].KeyEvent); } return; } @@ -79,15 +79,15 @@ protected override void WndProc(ref Message m) public HookGlobalHotkey(Form targetForm) { - this._targetForm = targetForm; - this._hotkeyID = new Dictionary(); + this.targetForm = targetForm; + this.hotkeyID = new Dictionary(); - this._targetForm.HandleCreated += this.OnHandleCreated; - this._targetForm.HandleDestroyed += this.OnHandleDestroyed; + this.targetForm.HandleCreated += this.OnHandleCreated; + this.targetForm.HandleDestroyed += this.OnHandleDestroyed; } public void OnHandleCreated(object sender, EventArgs e) - => this.AssignHandle(this._targetForm.Handle); + => this.AssignHandle(this.targetForm.Handle); public void OnHandleDestroyed(object sender, EventArgs e) => this.ReleaseHandle(); @@ -100,14 +100,14 @@ public bool RegisterOriginalHotkey(Keys hotkey, int hotkeyValue, ModKeys modifie if ((modifiers & ModKeys.Shift) == ModKeys.Shift) modKey |= Keys.Shift; if ((modifiers & ModKeys.Win) == ModKeys.Win) modKey |= Keys.LWin; var key = new KeyEventArgs(hotkey | modKey); - foreach (var (_, value) in this._hotkeyID) + foreach (var (_, value) in this.hotkeyID) { if (value.KeyEvent.KeyData == key.KeyData && value.Value == hotkeyValue) return true; // 登録済みなら正常終了 } - var hotkeyId = NativeMethods.RegisterGlobalHotKey(hotkeyValue, (int)modifiers, this._targetForm); + var hotkeyId = NativeMethods.RegisterGlobalHotKey(hotkeyValue, (int)modifiers, this.targetForm); if (hotkeyId > 0) { - this._hotkeyID.Add(hotkeyId, new KeyEventValue(key, hotkeyValue)); + this.hotkeyID.Add(hotkeyId, new KeyEventValue(key, hotkeyValue)); return true; } return false; @@ -115,11 +115,11 @@ public bool RegisterOriginalHotkey(Keys hotkey, int hotkeyValue, ModKeys modifie public void UnregisterAllOriginalHotkey() { - foreach (ushort hotkeyId in this._hotkeyID.Keys) + foreach (ushort hotkeyId in this.hotkeyID.Keys) { - NativeMethods.UnregisterGlobalHotKey(hotkeyId, this._targetForm); + NativeMethods.UnregisterGlobalHotKey(hotkeyId, this.targetForm); } - this._hotkeyID.Clear(); + this.hotkeyID.Clear(); } private bool disposedValue = false; // 重複する呼び出しを検出するには @@ -133,11 +133,11 @@ protected virtual void Dispose(bool disposing) { } - if (this._targetForm != null && !this._targetForm.IsDisposed) + if (this.targetForm != null && !this.targetForm.IsDisposed) { this.UnregisterAllOriginalHotkey(); - this._targetForm.HandleCreated -= this.OnHandleCreated; - this._targetForm.HandleDestroyed -= this.OnHandleDestroyed; + this.targetForm.HandleCreated -= this.OnHandleCreated; + this.targetForm.HandleDestroyed -= this.OnHandleDestroyed; } } this.disposedValue = true; diff --git a/OpenTween/ListElement.cs b/OpenTween/ListElement.cs index 68652d005..08e239e2a 100644 --- a/OpenTween/ListElement.cs +++ b/OpenTween/ListElement.cs @@ -46,9 +46,9 @@ public class ListElement public string Username = ""; public string Nickname = ""; - protected Twitter _tw = null!; + protected Twitter tw = null!; - private List _members = new List(); + private List members = new List(); [XmlIgnore] public long Cursor { get; private set; } = -1; @@ -70,12 +70,12 @@ public ListElement(TwitterList listElementData, Twitter tw) this.Username = listElementData.User.ScreenName; this.UserId = listElementData.User.Id; - this._tw = tw; + this.tw = tw; } public virtual async Task Refresh() { - var newList = await this._tw.EditList(this.Id, this.Name, !this.IsPublic, this.Description) + var newList = await this.tw.EditList(this.Id, this.Name, !this.IsPublic, this.Description) .ConfigureAwait(false); this.Description = newList.Description; @@ -92,18 +92,18 @@ public virtual async Task Refresh() [XmlIgnore] public List Members - => this._members; + => this.members; public async Task RefreshMembers() { var users = new List(); - this.Cursor = await this._tw.GetListMembers(this.Id, users, cursor: -1) + this.Cursor = await this.tw.GetListMembers(this.Id, users, cursor: -1) .ConfigureAwait(false); - this._members = users; + this.members = users; } public async Task GetMoreMembers() - => this.Cursor = await this._tw.GetListMembers(this.Id, this._members, this.Cursor) + => this.Cursor = await this.tw.GetListMembers(this.Id, this.members, this.Cursor) .ConfigureAwait(false); public override string ToString() diff --git a/OpenTween/ListManage.cs b/OpenTween/ListManage.cs index ed09b637b..ef81c177d 100644 --- a/OpenTween/ListManage.cs +++ b/OpenTween/ListManage.cs @@ -417,7 +417,7 @@ private class NewListElement : ListElement public bool IsCreated { get; private set; } = false; public NewListElement(Twitter tw) - => this._tw = tw; + => this.tw = tw; public override async Task Refresh() { @@ -427,7 +427,7 @@ public override async Task Refresh() } else { - await this._tw.CreateListApi(this.Name, !this.IsPublic, this.Description) + await this.tw.CreateListApi(this.Name, !this.IsPublic, this.Description) .ConfigureAwait(false); this.IsCreated = true; diff --git a/OpenTween/MediaItem.cs b/OpenTween/MediaItem.cs index 82d33f48d..122b305a0 100644 --- a/OpenTween/MediaItem.cs +++ b/OpenTween/MediaItem.cs @@ -170,17 +170,17 @@ public void CopyTo(Stream stream) public class MemoryImageMediaItem : IMediaItem, IDisposable { public const string PathPrefix = "<>MemoryImage://"; - private static int _fileNumber = 0; - private readonly MemoryImage _image; + private static int fileNumber = 0; + private readonly MemoryImage image; public bool IsDisposed { get; private set; } = false; public MemoryImageMediaItem(MemoryImage image) { - this._image = image ?? throw new ArgumentNullException(nameof(image)); + this.image = image ?? throw new ArgumentNullException(nameof(image)); - var num = Interlocked.Increment(ref _fileNumber); - this.Path = PathPrefix + num + this._image.ImageFormatExt; + var num = Interlocked.Increment(ref fileNumber); + this.Path = PathPrefix + num + this.image.ImageFormatExt; } public string Path { get; } @@ -190,19 +190,19 @@ public string Name => this.Path.Substring(PathPrefix.Length); public string Extension - => this._image.ImageFormatExt; + => this.image.ImageFormatExt; public bool Exists - => this._image != null; + => this.image != null; public long Size - => this._image.Stream.Length; + => this.image.Stream.Length; public bool IsImage => true; public MemoryImage CreateImage() - => this._image.Clone(); + => this.image.Clone(); public Stream OpenRead() { @@ -212,7 +212,7 @@ public Stream OpenRead() // コピーを作成する memstream = new MemoryStream(); - this._image.Stream.WriteTo(memstream); + this.image.Stream.WriteTo(memstream); memstream.Seek(0, SeekOrigin.Begin); return memstream; @@ -225,7 +225,7 @@ public Stream OpenRead() } public void CopyTo(Stream stream) - => this._image.Stream.WriteTo(stream); + => this.image.Stream.WriteTo(stream); protected virtual void Dispose(bool disposing) { @@ -233,7 +233,7 @@ protected virtual void Dispose(bool disposing) if (disposing) { - this._image.Dispose(); + this.image.Dispose(); } this.IsDisposed = true; diff --git a/OpenTween/Models/FilterTabModel.cs b/OpenTween/Models/FilterTabModel.cs index 56da45be7..be492a5d2 100644 --- a/OpenTween/Models/FilterTabModel.cs +++ b/OpenTween/Models/FilterTabModel.cs @@ -43,7 +43,7 @@ public override MyCommon.TabUsageType TabType public bool FilterModified { get; set; } - private readonly List _filters = new List(); + private readonly List filters = new List(); private readonly object lockObjFilters = new object(); public FilterTabModel(string tabName) @@ -62,7 +62,7 @@ public MyCommon.HITRESULT AddFiltered(PostClass post, bool immediately = false) // 全フィルタ評価(優先順位あり) lock (this.lockObjFilters) { - foreach (var ft in this._filters) + foreach (var ft in this.filters) { try { @@ -112,7 +112,7 @@ public PostFilterRule[] GetFilters() { lock (this.lockObjFilters) { - return this._filters.ToArray(); + return this.filters.ToArray(); } } @@ -120,7 +120,7 @@ public void RemoveFilter(PostFilterRule filter) { lock (this.lockObjFilters) { - this._filters.Remove(filter); + this.filters.Remove(filter); filter.PropertyChanged -= this.OnFilterModified; this.FilterModified = true; } @@ -130,9 +130,9 @@ public bool AddFilter(PostFilterRule filter) { lock (this.lockObjFilters) { - if (this._filters.Contains(filter)) return false; + if (this.filters.Contains(filter)) return false; filter.PropertyChanged += this.OnFilterModified; - this._filters.Add(filter); + this.filters.Add(filter); this.FilterModified = true; return true; } @@ -147,24 +147,24 @@ public PostFilterRule[] FilterArray { lock (this.lockObjFilters) { - return this._filters.ToArray(); + return this.filters.ToArray(); } } set { lock (this.lockObjFilters) { - foreach (var oldFilter in this._filters) + foreach (var oldFilter in this.filters) { oldFilter.PropertyChanged -= this.OnFilterModified; } - this._filters.Clear(); + this.filters.Clear(); this.FilterModified = true; foreach (var newFilter in value) { - this._filters.Add(newFilter); + this.filters.Add(newFilter); newFilter.PropertyChanged += this.OnFilterModified; } } diff --git a/OpenTween/Models/PostClass.cs b/OpenTween/Models/PostClass.cs index 173dbf1d6..e0e3bc02b 100644 --- a/OpenTween/Models/PostClass.cs +++ b/OpenTween/Models/PostClass.cs @@ -77,33 +77,33 @@ public bool Equals(StatusGeo other) public string ScreenName { get; set; } = ""; public DateTimeUtc CreatedAt { get; set; } public long StatusId { get; set; } - private bool _IsFav; + private bool isFav; public string Text { get { if (this.expandComplatedAll) - return this._text; + return this.text; - var expandedHtml = this.ReplaceToExpandedUrl(this._text, out this.expandComplatedAll); + var expandedHtml = this.ReplaceToExpandedUrl(this.text, out this.expandComplatedAll); if (this.expandComplatedAll) - this._text = expandedHtml; + this.text = expandedHtml; return expandedHtml; } - set => this._text = value; + set => this.text = value; } - private string _text = ""; + private string text = ""; public bool IsRead { get; set; } public bool IsReply { get; set; } public bool IsExcludeReply { get; set; } - private bool _IsProtect; + private bool isProtect; public bool IsOwl { get; set; } - private bool _IsMark; + private bool isMark; public string? InReplyToUser { get; set; } - private long? _InReplyToStatusId; + private long? inReplyToStatusId; public string Source { get; set; } = ""; public Uri? SourceUri { get; set; } public List<(long UserId, string ScreenName)> ReplyToList { get; set; } @@ -113,8 +113,8 @@ public string Text public bool FilterHit { get; set; } public string? RetweetedBy { get; set; } public long? RetweetedId { get; set; } - private bool _IsDeleted = false; - private StatusGeo? _postGeo = null; + private bool isDeleted = false; + private StatusGeo? postGeo = null; public int RetweetedCount { get; set; } public long? RetweetedByUserId { get; set; } public long? InReplyToUserId { get; set; } @@ -134,7 +134,7 @@ public class ExpandedUrlInfo : ICloneable /// /// による展開が完了するまでは Entity に含まれる expanded_url の値を返します /// - public string ExpandedUrl => this._expandedUrl; + public string ExpandedUrl => this.expandedUrl; /// による展開を行うタスク public Task ExpandTask { get; private set; } @@ -142,7 +142,7 @@ public class ExpandedUrlInfo : ICloneable /// による展開が完了したか否か public bool ExpandedCompleted => this.ExpandTask.IsCompleted; - protected string _expandedUrl; + protected string expandedUrl; public ExpandedUrlInfo(string url, string expandedUrl) : this(url, expandedUrl, deepExpand: true) @@ -152,7 +152,7 @@ public ExpandedUrlInfo(string url, string expandedUrl) public ExpandedUrlInfo(string url, string expandedUrl, bool deepExpand) { this.Url = url; - this._expandedUrl = expandedUrl; + this.expandedUrl = expandedUrl; if (deepExpand) this.ExpandTask = this.DeepExpandAsync(); @@ -162,11 +162,11 @@ public ExpandedUrlInfo(string url, string expandedUrl, bool deepExpand) protected virtual async Task DeepExpandAsync() { - var origUrl = this._expandedUrl; + var origUrl = this.expandedUrl; var newUrl = await ShortUrl.Instance.ExpandUrlAsync(origUrl) .ConfigureAwait(false); - Interlocked.CompareExchange(ref this._expandedUrl, newUrl, origUrl); + Interlocked.CompareExchange(ref this.expandedUrl, newUrl, origUrl); } public ExpandedUrlInfo Clone() @@ -178,7 +178,7 @@ object ICloneable.Clone() public int FavoritedCount { get; set; } - private States _states = States.None; + private States states = States.None; private bool expandComplatedAll = false; [Flags] @@ -215,11 +215,11 @@ public bool IsFav } } - return this._IsFav; + return this.isFav; } set { - this._IsFav = value; + this.isFav = value; if (this.RetweetedId != null) { var post = this.RetweetSource; @@ -233,47 +233,47 @@ public bool IsFav public bool IsProtect { - get => this._IsProtect; + get => this.isProtect; set { if (value) - this._states |= States.Protect; + this.states |= States.Protect; else - this._states &= ~States.Protect; + this.states &= ~States.Protect; - this._IsProtect = value; + this.isProtect = value; } } public bool IsMark { - get => this._IsMark; + get => this.isMark; set { if (value) - this._states |= States.Mark; + this.states |= States.Mark; else - this._states &= ~States.Mark; + this.states &= ~States.Mark; - this._IsMark = value; + this.isMark = value; } } public long? InReplyToStatusId { - get => this._InReplyToStatusId; + get => this.inReplyToStatusId; set { if (value != null) - this._states |= States.Reply; + this.states |= States.Reply; else - this._states &= ~States.Reply; + this.states &= ~States.Reply; - this._InReplyToStatusId = value; + this.inReplyToStatusId = value; } } public bool IsDeleted { - get => this._IsDeleted; + get => this.isDeleted; set { if (value) @@ -283,9 +283,9 @@ public bool IsDeleted this.InReplyToUserId = null; this.IsReply = false; this.ReplyToList = new List<(long, string)>(); - this._states = States.None; + this.states = States.None; } - this._IsDeleted = value; + this.isDeleted = value; } } @@ -294,23 +294,23 @@ protected virtual PostClass? RetweetSource public StatusGeo? PostGeo { - get => this._postGeo; + get => this.postGeo; set { if (value != null) { - this._states |= States.Geo; + this.states |= States.Geo; } else { - this._states &= ~States.Geo; + this.states &= ~States.Geo; } - this._postGeo = value; + this.postGeo = value; } } public int StateIndex - => (int)this._states - 1; + => (int)this.states - 1; // 互換性のために用意 public string SourceHtml diff --git a/OpenTween/Models/PostFilterRule.cs b/OpenTween/Models/PostFilterRule.cs index f5f86f3da..069e46f14 100644 --- a/OpenTween/Models/PostFilterRule.cs +++ b/OpenTween/Models/PostFilterRule.cs @@ -49,7 +49,7 @@ public class PostFilterRule : NotifyPropertyChangedBase, IEquatable [XmlIgnore] - protected Func? FilterDelegate; + protected Func? filterDelegate; /// /// 振り分けルールの概要 @@ -68,164 +68,164 @@ public string SummaryText public bool Enabled { - get => this._enabled; - set => this.SetProperty(ref this._enabled, value); + get => this.enabled; + set => this.SetProperty(ref this.enabled, value); } - private bool _enabled; + private bool enabled; [XmlElement("NameFilter")] public string? FilterName { - get => this._FilterName; - set => this.SetProperty(ref this._FilterName, value); + get => this.filterName; + set => this.SetProperty(ref this.filterName, value); } - private string? _FilterName; + private string? filterName; [XmlElement("ExNameFilter")] public string? ExFilterName { - get => this._ExFilterName; - set => this.SetProperty(ref this._ExFilterName, value); + get => this.exFilterName; + set => this.SetProperty(ref this.exFilterName, value); } - private string? _ExFilterName; + private string? exFilterName; [XmlArray("BodyFilterArray")] public string[] FilterBody { - get => this._FilterBody; - set => this.SetProperty(ref this._FilterBody, value ?? throw new ArgumentNullException(nameof(value))); + get => this.filterBody; + set => this.SetProperty(ref this.filterBody, value ?? throw new ArgumentNullException(nameof(value))); } - private string[] _FilterBody = Array.Empty(); + private string[] filterBody = Array.Empty(); [XmlArray("ExBodyFilterArray")] public string[] ExFilterBody { - get => this._ExFilterBody; - set => this.SetProperty(ref this._ExFilterBody, value ?? throw new ArgumentNullException(nameof(value))); + get => this.exFilterBody; + set => this.SetProperty(ref this.exFilterBody, value ?? throw new ArgumentNullException(nameof(value))); } - private string[] _ExFilterBody = Array.Empty(); + private string[] exFilterBody = Array.Empty(); [XmlElement("SearchBoth")] public bool UseNameField { - get => this._UseNameField; - set => this.SetProperty(ref this._UseNameField, value); + get => this.useNameField; + set => this.SetProperty(ref this.useNameField, value); } - private bool _UseNameField; + private bool useNameField; [XmlElement("ExSearchBoth")] public bool ExUseNameField { - get => this._ExUseNameField; - set => this.SetProperty(ref this._ExUseNameField, value); + get => this.exUseNameField; + set => this.SetProperty(ref this.exUseNameField, value); } - private bool _ExUseNameField; + private bool exUseNameField; [XmlElement("MoveFrom")] public bool MoveMatches { - get => this._MoveMatches; - set => this.SetProperty(ref this._MoveMatches, value); + get => this.moveMatches; + set => this.SetProperty(ref this.moveMatches, value); } - private bool _MoveMatches; + private bool moveMatches; [XmlElement("SetMark")] public bool MarkMatches { - get => this._MarkMatches; - set => this.SetProperty(ref this._MarkMatches, value); + get => this.markMatches; + set => this.SetProperty(ref this.markMatches, value); } - private bool _MarkMatches; + private bool markMatches; [XmlElement("SearchUrl")] public bool FilterByUrl { - get => this._FilterByUrl; - set => this.SetProperty(ref this._FilterByUrl, value); + get => this.filterByUrl; + set => this.SetProperty(ref this.filterByUrl, value); } - private bool _FilterByUrl; + private bool filterByUrl; [XmlElement("ExSearchUrl")] public bool ExFilterByUrl { - get => this._ExFilterByUrl; - set => this.SetProperty(ref this._ExFilterByUrl, value); + get => this.exFilterByUrl; + set => this.SetProperty(ref this.exFilterByUrl, value); } - private bool _ExFilterByUrl; + private bool exFilterByUrl; public bool CaseSensitive { - get => this._CaseSensitive; - set => this.SetProperty(ref this._CaseSensitive, value); + get => this.caseSensitive; + set => this.SetProperty(ref this.caseSensitive, value); } - private bool _CaseSensitive; + private bool caseSensitive; public bool ExCaseSensitive { - get => this._ExCaseSensitive; - set => this.SetProperty(ref this._ExCaseSensitive, value); + get => this.exCaseSensitive; + set => this.SetProperty(ref this.exCaseSensitive, value); } - private bool _ExCaseSensitive; + private bool exCaseSensitive; public bool UseLambda { - get => this._UseLambda; - set => this.SetProperty(ref this._UseLambda, value); + get => this.useLambda; + set => this.SetProperty(ref this.useLambda, value); } - private bool _UseLambda; + private bool useLambda; public bool ExUseLambda { - get => this._ExUseLambda; - set => this.SetProperty(ref this._ExUseLambda, value); + get => this.exUseLambda; + set => this.SetProperty(ref this.exUseLambda, value); } - private bool _ExUseLambda; + private bool exUseLambda; public bool UseRegex { - get => this._UseRegex; - set => this.SetProperty(ref this._UseRegex, value); + get => this.useRegex; + set => this.SetProperty(ref this.useRegex, value); } - private bool _UseRegex; + private bool useRegex; public bool ExUseRegex { - get => this._ExUseRegex; - set => this.SetProperty(ref this._ExUseRegex, value); + get => this.exUseRegex; + set => this.SetProperty(ref this.exUseRegex, value); } - private bool _ExUseRegex; + private bool exUseRegex; [XmlElement("IsRt")] public bool FilterRt { - get => this._FilterRt; - set => this.SetProperty(ref this._FilterRt, value); + get => this.filterRt; + set => this.SetProperty(ref this.filterRt, value); } - private bool _FilterRt; + private bool filterRt; [XmlElement("IsExRt")] public bool ExFilterRt { - get => this._ExFilterRt; - set => this.SetProperty(ref this._ExFilterRt, value); + get => this.exFilterRt; + set => this.SetProperty(ref this.exFilterRt, value); } - private bool _ExFilterRt; + private bool exFilterRt; [XmlElement("Source")] public string? FilterSource { - get => this._FilterSource; - set => this.SetProperty(ref this._FilterSource, value); + get => this.filterSource; + set => this.SetProperty(ref this.filterSource, value); } - private string? _FilterSource; + private string? filterSource; [XmlElement("ExSource")] public string? ExFilterSource { - get => this._ExFilterSource; - set => this.SetProperty(ref this._ExFilterSource, value); + get => this.exFilterSource; + set => this.SetProperty(ref this.exFilterSource, value); } - private string? _ExFilterSource; + private string? exFilterSource; public PostFilterRule() { @@ -248,7 +248,7 @@ public void Compile() { if (!this.Enabled) { - this.FilterDelegate = x => MyCommon.HITRESULT.None; + this.filterDelegate = x => MyCommon.HITRESULT.None; this.IsDirty = false; return; } @@ -334,7 +334,7 @@ public void Compile() filterExpr = x => MyCommon.HITRESULT.None; } - this.FilterDelegate = filterExpr.Compile(); + this.filterDelegate = filterExpr.Compile(); this.IsDirty = false; } @@ -504,7 +504,7 @@ public MyCommon.HITRESULT ExecFilter(PostClass post) this.Compile(); } - return this.FilterDelegate!(post); + return this.filterDelegate!(post); } public PostFilterRule Clone() diff --git a/OpenTween/Models/PublicSearchTabModel.cs b/OpenTween/Models/PublicSearchTabModel.cs index 852e4c361..d3baa449e 100644 --- a/OpenTween/Models/PublicSearchTabModel.cs +++ b/OpenTween/Models/PublicSearchTabModel.cs @@ -43,26 +43,26 @@ public override MyCommon.TabUsageType TabType public string SearchWords { - get => this._searchWords; + get => this.searchWords; set { - this._searchWords = value; + this.searchWords = value; this.ResetFetchIds(); } } public string SearchLang { - get => this._searchLang; + get => this.searchLang; set { - this._searchLang = value; + this.searchLang = value; this.ResetFetchIds(); } } - private string _searchWords = ""; - private string _searchLang = ""; + private string searchWords = ""; + private string searchLang = ""; public PublicSearchTabModel(string tabName) : base(tabName) diff --git a/OpenTween/Models/RelatedPostsTabModel.cs b/OpenTween/Models/RelatedPostsTabModel.cs index be635dc19..36b646bf5 100644 --- a/OpenTween/Models/RelatedPostsTabModel.cs +++ b/OpenTween/Models/RelatedPostsTabModel.cs @@ -54,7 +54,7 @@ public RelatedPostsTabModel(string tabName, PostClass targetPost) public Task RefreshAsync(Twitter tw, bool startup, IProgress progress) => this.RefreshAsync(tw, false, startup, progress); - public override async Task RefreshAsync(Twitter tw, bool _, bool startup, IProgress progress) + public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress) { bool read; if (!SettingManager.Common.UnreadManage) diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index 9d17e727f..170afae29 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -49,7 +49,7 @@ public IReadOnlyTabCollection Tabs public ConcurrentDictionary Posts { get; } = new ConcurrentDictionary(); - private readonly Dictionary _quotes = new Dictionary(); + private readonly Dictionary quotes = new Dictionary(); private readonly ConcurrentDictionary retweetsCount = new ConcurrentDictionary(); public Stack RemovedTab { get; } = new Stack(); @@ -74,12 +74,12 @@ public IReadOnlyTabCollection Tabs }; // トランザクション用 - private readonly object LockObj = new object(); + private readonly object lockObj = new object(); private static readonly TabInformations Instance = new TabInformations(); // List - private List _lists = new List(); + private List lists = new List(); private TabInformations() { @@ -98,7 +98,7 @@ public int SelectedTabIndex public List SubscribableLists { - get => this._lists; + get => this.lists; set { if (value.Count > 0) @@ -115,13 +115,13 @@ public List SubscribableLists } } } - this._lists = value; + this.lists = value; } } public bool AddTab(TabModel tab) { - lock (this.LockObj) + lock (this.lockObj) { if (tab is MuteTabModel muteTab) { @@ -139,11 +139,11 @@ public bool AddTab(TabModel tab) } } - public void RemoveTab(string TabName) + public void RemoveTab(string tabName) { - lock (this.LockObj) + lock (this.lockObj) { - var tb = this.GetTabByName(TabName); + var tb = this.GetTabByName(tabName); if (tb == null || tb.IsDefaultTabType) return; // 念のため if (!tb.IsInnerStorageTabType) @@ -154,24 +154,24 @@ public void RemoveTab(string TabName) for (var idx = 0; idx < tb.AllCount; ++idx) { var exist = false; - var Id = tb.GetStatusIdAt(idx); - if (Id < 0) continue; + var id = tb.GetStatusIdAt(idx); + if (id < 0) continue; foreach (var tab in this.Tabs) { if (tab != tb && tab != dmTab) { - if (tab.Contains(Id)) + if (tab.Contains(id)) { exist = true; break; } } } - if (!exist) homeTab.AddPostImmediately(Id, this.Posts[Id].IsRead); + if (!exist) homeTab.AddPostImmediately(id, this.Posts[id].IsRead); } } this.RemovedTab.Push(tb); - this.tabs.Remove(TabName); + this.tabs.Remove(tabName); } } @@ -194,8 +194,8 @@ public void MoveTab(int newIndex, TabModel tab) this.tabs.Insert(newIndex, tab); } - public bool ContainsTab(string TabText) - => this.Tabs.Contains(TabText); + public bool ContainsTab(string tabText) + => this.Tabs.Contains(tabText); public bool ContainsTab(TabModel ts) => this.Tabs.Contains(ts); @@ -306,8 +306,8 @@ public SortOrder ToggleSortOrder(ComparerMode sortMode) return this.SortOrder; } - public PostClass? RetweetSource(long Id) - => this.Posts.TryGetValue(Id, out var status) ? status : null; + public PostClass? RetweetSource(long id) + => this.Posts.TryGetValue(id, out var status) ? status : null; public void RemovePostFromAllTabs(long statusId, bool setIsDeleted) { @@ -333,7 +333,7 @@ public int SubmitUpdate( out bool isDeletePost) { // 注:メインスレッドから呼ぶこと - lock (this.LockObj) + lock (this.lockObj) { soundFile = ""; notifyPosts = Array.Empty(); @@ -420,7 +420,7 @@ public int SubmitUpdate( public int DistributePosts() { - lock (this.LockObj) + lock (this.lockObj) { var homeTab = this.HomeTab; var replyTab = this.MentionTab; @@ -489,26 +489,26 @@ public int DistributePosts() } } - public void AddPost(PostClass Item) + public void AddPost(PostClass item) { - Debug.Assert(!Item.IsDm, "DM は TabClass.AddPostToInnerStorage を使用する"); + Debug.Assert(!item.IsDm, "DM は TabClass.AddPostToInnerStorage を使用する"); - lock (this.LockObj) + lock (this.lockObj) { - if (this.IsMuted(Item, isHomeTimeline: true)) + if (this.IsMuted(item, isHomeTimeline: true)) return; - if (this.Posts.TryGetValue(Item.StatusId, out var status)) + if (this.Posts.TryGetValue(item.StatusId, out var status)) { - if (Item.IsFav) + if (item.IsFav) { - if (Item.RetweetedId == null) + if (item.RetweetedId == null) { status.IsFav = true; } else { - Item.IsFav = false; + item.IsFav = false; } } else @@ -518,27 +518,27 @@ public void AddPost(PostClass Item) } else { - if (Item.IsFav && Item.RetweetedId != null) Item.IsFav = false; + if (item.IsFav && item.RetweetedId != null) item.IsFav = false; // 既に持っている公式RTは捨てる - if (Item.RetweetedId != null && SettingManager.Common.HideDuplicatedRetweets) + if (item.RetweetedId != null && SettingManager.Common.HideDuplicatedRetweets) { - var retweetCount = this.UpdateRetweetCount(Item); + var retweetCount = this.UpdateRetweetCount(item); - if (retweetCount > 1 && !Item.IsMe) + if (retweetCount > 1 && !item.IsMe) return; } - if (this.BlockIds.Contains(Item.UserId)) + if (this.BlockIds.Contains(item.UserId)) return; - this.Posts.TryAdd(Item.StatusId, Item); + this.Posts.TryAdd(item.StatusId, item); } - if (Item.IsFav && this.retweetsCount.ContainsKey(Item.StatusId)) + if (item.IsFav && this.retweetsCount.ContainsKey(item.StatusId)) { return; // Fav済みのRetweet元発言は追加しない } - this.addQueue.Enqueue(Item.StatusId); + this.addQueue.Enqueue(item.StatusId); } } @@ -580,12 +580,12 @@ private int UpdateRetweetCount(PostClass retweetPost) public bool AddQuoteTweet(PostClass item) { - lock (this.LockObj) + lock (this.lockObj) { if (this.IsMuted(item, isHomeTimeline: false) || this.BlockIds.Contains(item.UserId)) return false; - this._quotes[item.StatusId] = item; + this.quotes[item.StatusId] = item; return true; } } @@ -598,7 +598,7 @@ public bool AddQuoteTweet(PostClass item) /// 既読状態に変化があれば true、変化がなければ false public bool SetReadAllTab(long statusId, bool read) { - lock (this.LockObj) + lock (this.lockObj) { foreach (var tab in this.Tabs) { @@ -624,7 +624,7 @@ public void SetReadHomeTab() { var homeTab = this.HomeTab; - lock (this.LockObj) + lock (this.lockObj) { foreach (var statusId in homeTab.GetUnreadIds()) { @@ -639,42 +639,42 @@ public void SetReadHomeTab() } } - public PostClass? this[long ID] + public PostClass? this[long id] { get { - if (this.Posts.TryGetValue(ID, out var status)) + if (this.Posts.TryGetValue(id, out var status)) return status; - if (this._quotes.TryGetValue(ID, out status)) + if (this.quotes.TryGetValue(id, out status)) return status; return this.GetTabsInnerStorageType() - .Select(x => x.Posts.TryGetValue(ID, out status) ? status : null) + .Select(x => x.Posts.TryGetValue(id, out status) ? status : null) .FirstOrDefault(x => x != null); } } - public bool ContainsKey(long Id) + public bool ContainsKey(long id) { // DM,公式検索は非対応 - lock (this.LockObj) + lock (this.lockObj) { - return this.Posts.ContainsKey(Id); + return this.Posts.ContainsKey(id); } } - public void RenameTab(string Original, string NewName) + public void RenameTab(string original, string newName) { - lock (this.LockObj) + lock (this.lockObj) { - var index = this.Tabs.IndexOf(Original); - var tb = this.Tabs[Original]; + var index = this.Tabs.IndexOf(original); + var tb = this.Tabs[original]; this.tabs.RemoveAt(index); - tb.TabName = NewName; + tb.TabName = newName; - if (this.SelectedTabName == Original) - this.SelectedTabName = NewName; + if (this.SelectedTabName == original) + this.SelectedTabName = newName; this.tabs.Insert(index, tb); } @@ -682,7 +682,7 @@ public void RenameTab(string Original, string NewName) public void FilterAll() { - lock (this.LockObj) + lock (this.lockObj) { var homeTab = this.HomeTab; var detachedIdsAll = Enumerable.Empty(); @@ -774,27 +774,27 @@ public void FilterAll() } } - public void ClearTabIds(string TabName) + public void ClearTabIds(string tabName) { // 不要なPostを削除 - lock (this.LockObj) + lock (this.lockObj) { - var tb = this.Tabs[TabName]; + var tb = this.Tabs[tabName]; if (!tb.IsInnerStorageTabType) { - foreach (var Id in tb.StatusIds) + foreach (var id in tb.StatusIds) { - var Hit = false; + var hit = false; foreach (var tab in this.Tabs) { - if (tab.Contains(Id)) + if (tab.Contains(id)) { - Hit = true; + hit = true; break; } } - if (!Hit) - this.Posts.TryRemove(Id, out var removedPost); + if (!hit) + this.Posts.TryRemove(id, out var removedPost); } } @@ -805,7 +805,7 @@ public void ClearTabIds(string TabName) public void RefreshOwl(ISet follower) { - lock (this.LockObj) + lock (this.lockObj) { if (follower.Count > 0) { @@ -848,7 +848,7 @@ public FavoritesTabModel FavoriteTab // Home,Mentions,DM,Favは1つに制限する // その他のタイプを指定されたら、最初に合致したものを返す // 合致しなければnullを返す - lock (this.LockObj) + lock (this.lockObj) { return this.Tabs.FirstOrDefault(x => x.TabType.HasFlag(tabType)); } @@ -857,13 +857,13 @@ public FavoritesTabModel FavoriteTab public T? GetTabByType() where T : TabModel { - lock (this.LockObj) + lock (this.lockObj) return this.Tabs.OfType().FirstOrDefault(); } public TabModel[] GetTabsByType(MyCommon.TabUsageType tabType) { - lock (this.LockObj) + lock (this.lockObj) { return this.Tabs .Where(x => x.TabType.HasFlag(tabType)) @@ -874,13 +874,13 @@ public TabModel[] GetTabsByType(MyCommon.TabUsageType tabType) public T[] GetTabsByType() where T : TabModel { - lock (this.LockObj) + lock (this.lockObj) return this.Tabs.OfType().ToArray(); } public TabModel[] GetTabsInnerStorageType() { - lock (this.LockObj) + lock (this.lockObj) { return this.Tabs .Where(x => x.IsInnerStorageTabType) @@ -890,7 +890,7 @@ public TabModel[] GetTabsInnerStorageType() public TabModel? GetTabByName(string tabName) { - lock (this.LockObj) + lock (this.lockObj) { return this.Tabs.TryGetValue(tabName, out var tab) ? tab diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index 9009edfd5..f53bc1719 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -59,8 +59,8 @@ public abstract class TabModel public virtual ConcurrentDictionary Posts => TabInformations.GetInstance().Posts; - public int AllCount => this._ids.Count; - public long[] StatusIds => this._ids.ToArray(); + public int AllCount => this.ids.Count; + public long[] StatusIds => this.ids.ToArray(); public bool IsDefaultTabType => this.TabType.IsDefault(); public bool IsDistributableTabType => this.TabType.IsDistributable(); @@ -92,13 +92,13 @@ public int SelectedIndex } } - private IndexedSortedSet _ids = new IndexedSortedSet(); + private IndexedSortedSet ids = new IndexedSortedSet(); private ConcurrentQueue addQueue = new ConcurrentQueue(); private readonly ConcurrentQueue removeQueue = new ConcurrentQueue(); private SortedSet unreadIds = new SortedSet(); private List selectedStatusIds = new List(); - private readonly object _lockObj = new object(); + private readonly object lockObj = new object(); protected TabModel(string tabName) => this.TabName = tabName; @@ -128,7 +128,7 @@ public virtual void AddPostQueue(PostClass post) // 無条件に追加 internal bool AddPostImmediately(long statusId, bool read) { - if (!this._ids.Add(statusId)) + if (!this.ids.Add(statusId)) return false; if (!read) @@ -155,7 +155,7 @@ public virtual void EnqueueRemovePost(long statusId, bool setIsDeleted) public virtual bool RemovePostImmediately(long statusId) { - if (!this._ids.Remove(statusId)) + if (!this.ids.Remove(statusId)) return false; this.unreadIds.Remove(statusId); @@ -191,7 +191,7 @@ bool IsValidIndex(int index) public virtual void ClearIDs() { - this._ids.Clear(); + this.ids.Clear(); this.unreadIds.Clear(); this.selectedStatusIds.Clear(); @@ -263,7 +263,7 @@ private void ApplySortMode() var comparer = Comparer.Create(comparison); - this._ids = new IndexedSortedSet(this._ids, comparer); + this.ids = new IndexedSortedSet(this.ids, comparer); this.unreadIds = new SortedSet(this.unreadIds, comparer); } @@ -320,7 +320,7 @@ public int UnreadCount /// public long[] GetUnreadIds() { - lock (this._lockObj) + lock (this.lockObj) return this.unreadIds.ToArray(); } @@ -335,7 +335,7 @@ public long[] GetUnreadIds() /// 既読状態に変化があれば true、変化がなければ false internal virtual bool SetReadState(long statusId, bool read) { - if (!this._ids.Contains(statusId)) + if (!this.ids.Contains(statusId)) throw new ArgumentOutOfRangeException(nameof(statusId)); if (read) @@ -345,7 +345,7 @@ internal virtual bool SetReadState(long statusId, bool read) } public bool Contains(long statusId) - => this._ids.Contains(statusId); + => this.ids.Contains(statusId); public PostClass this[int index] { @@ -387,7 +387,7 @@ public long[] GetStatusIdAt(IEnumerable indexes) => indexes.Select(x => this.GetStatusIdAt(x)).ToArray(); public long GetStatusIdAt(int index) - => this._ids[index]; + => this.ids[index]; public int[] IndexOf(long[] statusIds) { @@ -398,7 +398,7 @@ public int[] IndexOf(long[] statusIds) } public int IndexOf(long statusId) - => this._ids.IndexOf(statusId); + => this.ids.IndexOf(statusId); public IEnumerable SearchPostsAll(Func stringComparer) => this.SearchPostsAll(stringComparer, reverse: false); diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 691353826..83b053f65 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -215,20 +215,20 @@ public static void TraceOut(WebApiException ex) TraceOut(TraceFlag, message); } - public static void TraceOut(Exception ex, string Message) + public static void TraceOut(Exception ex, string message) { var buf = ExceptionOutMessage(ex); - TraceOut(TraceFlag, Message + Environment.NewLine + buf); + TraceOut(TraceFlag, message + Environment.NewLine + buf); } - public static void TraceOut(string Message) - => TraceOut(TraceFlag, Message); + public static void TraceOut(string message) + => TraceOut(TraceFlag, message); - public static void TraceOut(bool OutputFlag, string Message) + public static void TraceOut(bool outputFlag, string message) { lock (LockObj) { - if (!OutputFlag) return; + if (!outputFlag) return; var logPath = MyCommon.GetErrorLogPath(); if (!Directory.Exists(logPath)) @@ -248,7 +248,7 @@ public static void TraceOut(bool OutputFlag, string Message) writer.WriteLine(Properties.Resources.TraceOutText4, Environment.OSVersion.VersionString); writer.WriteLine(Properties.Resources.TraceOutText5, Environment.Version); writer.WriteLine(Properties.Resources.TraceOutText6, ApplicationSettings.AssemblyName, FileVersion); - writer.WriteLine(Message); + writer.WriteLine(message); writer.WriteLine(); } } @@ -260,11 +260,11 @@ public static void TraceOut(bool OutputFlag, string Message) public static string ExceptionOutMessage(Exception ex) { - var IsTerminatePermission = true; - return ExceptionOutMessage(ex, ref IsTerminatePermission); + var isTerminatePermission = true; + return ExceptionOutMessage(ex, ref isTerminatePermission); } - public static string ExceptionOutMessage(Exception ex, ref bool IsTerminatePermission) + public static string ExceptionOutMessage(Exception ex, ref bool isTerminatePermission) { if (ex == null) return ""; @@ -287,7 +287,7 @@ public static string ExceptionOutMessage(Exception ex, ref bool IsTerminatePermi buf.AppendLine(); if (dt.Key.Equals("IsTerminatePermission")) { - IsTerminatePermission = (bool)dt.Value; + isTerminatePermission = (bool)dt.Value; } } if (!needHeader) @@ -299,19 +299,19 @@ public static string ExceptionOutMessage(Exception ex, ref bool IsTerminatePermi buf.AppendLine(); // InnerExceptionが存在する場合書き出す - var _ex = ex.InnerException; + var innerException = ex.InnerException; var nesting = 0; - while (_ex != null) + while (innerException != null) { buf.AppendFormat("-----InnerException[{0}]-----\r\n", nesting); buf.AppendLine(); - buf.AppendFormat(Properties.Resources.UnhandledExceptionText8, _ex.GetType().FullName, _ex.Message); + buf.AppendFormat(Properties.Resources.UnhandledExceptionText8, innerException.GetType().FullName, innerException.Message); buf.AppendLine(); - if (_ex.Data != null) + if (innerException.Data != null) { var needHeader = true; - foreach (DictionaryEntry dt in _ex.Data) + foreach (DictionaryEntry dt in innerException.Data) { if (needHeader) { @@ -322,7 +322,7 @@ public static string ExceptionOutMessage(Exception ex, ref bool IsTerminatePermi buf.AppendFormat("{0} : {1}", dt.Key, dt.Value); if (dt.Key.Equals("IsTerminatePermission")) { - IsTerminatePermission = (bool)dt.Value; + isTerminatePermission = (bool)dt.Value; } } if (!needHeader) @@ -330,10 +330,10 @@ public static string ExceptionOutMessage(Exception ex, ref bool IsTerminatePermi buf.AppendLine("-----End Extra Information-----"); } } - buf.AppendLine(_ex.StackTrace); + buf.AppendLine(innerException.StackTrace); buf.AppendLine(); nesting++; - _ex = _ex.InnerException; + innerException = innerException.InnerException; } return buf.ToString(); } @@ -342,7 +342,7 @@ public static bool ExceptionOut(Exception ex) { lock (LockObj) { - var IsTerminatePermission = true; + var isTerminatePermission = true; var ident = WindowsIdentity.GetCurrent(); var princ = new WindowsPrincipal(ident); @@ -362,7 +362,7 @@ public static bool ExceptionOut(Exception ex) string.Format(Properties.Resources.UnhandledExceptionText6, Environment.Version), string.Format(Properties.Resources.UnhandledExceptionText7, ApplicationSettings.AssemblyName, FileVersion), - ExceptionOutMessage(ex, ref IsTerminatePermission)); + ExceptionOutMessage(ex, ref isTerminatePermission)); var logPath = MyCommon.GetErrorLogPath(); if (!Directory.Exists(logPath)) diff --git a/OpenTween/OTSplitContainer.cs b/OpenTween/OTSplitContainer.cs index 5571115d6..4a73651ac 100644 --- a/OpenTween/OTSplitContainer.cs +++ b/OpenTween/OTSplitContainer.cs @@ -39,12 +39,12 @@ public class OTSplitContainer : SplitContainer [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool IsPanelInverted { - get => this._isPanelInverted; + get => this.isPanelInverted; set { - if (this._isPanelInverted == value) + if (this.isPanelInverted == value) return; - this._isPanelInverted = value; + this.isPanelInverted = value; // Panel1 と Panel2 の中身を入れ替え using (ControlTransaction.Layout(this, false)) @@ -75,7 +75,7 @@ public bool IsPanelInverted } } } - private bool _isPanelInverted = false; + private bool isPanelInverted = false; /// /// SplitContainer.Orientation プロパティの設定に応じて、スプリッタが移動する方向の幅を返す。 diff --git a/OpenTween/OpenURL.cs b/OpenTween/OpenURL.cs index d019f7609..7bff34d81 100644 --- a/OpenTween/OpenURL.cs +++ b/OpenTween/OpenURL.cs @@ -39,7 +39,7 @@ namespace OpenTween { public partial class OpenURL : OTBaseForm { - private string? _selUrl; + private string? selUrl; public OpenURL() => this.InitializeComponent(); @@ -52,7 +52,7 @@ private void OK_Button_Click(object sender, EventArgs e) } else { - this._selUrl = this.UrlList.SelectedItem.ToString(); + this.selUrl = this.UrlList.SelectedItem.ToString(); this.DialogResult = DialogResult.OK; } this.Close(); @@ -75,7 +75,7 @@ public string SelectedUrl get { if (this.UrlList.SelectedItems.Count == 1) - return this._selUrl!; + return this.selUrl!; else return ""; } @@ -123,11 +123,11 @@ private void UrlList_KeyDown(object sender, KeyEventArgs e) public class OpenUrlItem { - private readonly string _linkText; + private readonly string linkText; public OpenUrlItem(string linkText, string url, string href) { - this._linkText = linkText; + this.linkText = linkText; this.Url = url; this.Href = href; } @@ -136,15 +136,15 @@ public string Text { get { - if (this._linkText.StartsWith("@", StringComparison.Ordinal) - || this._linkText.StartsWith("@", StringComparison.Ordinal) - || this._linkText.StartsWith("#", StringComparison.Ordinal) - || this._linkText.StartsWith("#", StringComparison.Ordinal)) - return this._linkText; - if (this._linkText.TrimEnd('/') == this.Url.TrimEnd('/')) + if (this.linkText.StartsWith("@", StringComparison.Ordinal) + || this.linkText.StartsWith("@", StringComparison.Ordinal) + || this.linkText.StartsWith("#", StringComparison.Ordinal) + || this.linkText.StartsWith("#", StringComparison.Ordinal)) + return this.linkText; + if (this.linkText.TrimEnd('/') == this.Url.TrimEnd('/')) return this.Url; else - return this._linkText + " >>> " + this.Url; + return this.linkText + " >>> " + this.Url; } } diff --git a/OpenTween/SendErrorReportForm.cs b/OpenTween/SendErrorReportForm.cs index 7bed261df..40a25ce4a 100644 --- a/OpenTween/SendErrorReportForm.cs +++ b/OpenTween/SendErrorReportForm.cs @@ -42,14 +42,14 @@ public partial class SendErrorReportForm : OTBaseForm { public ErrorReport ErrorReport { - get => this._errorReport; + get => this.errorReport; set { - this._errorReport = value; + this.errorReport = value; this.bindingSource.DataSource = value; } } - private ErrorReport _errorReport = null!; + private ErrorReport errorReport = null!; public SendErrorReportForm() => this.InitializeComponent(); @@ -94,39 +94,39 @@ public class ErrorReport : NotifyPropertyChangedBase { public string ReportText { - get => this._reportText; + get => this.reportText; set { - this.SetProperty(ref this._reportText, value); + this.SetProperty(ref this.reportText, value); this.UpdateEncodedReport(); } } - private string _reportText = ""; + private string reportText = ""; public bool AnonymousReport { - get => this._anonymousReport; + get => this.anonymousReport; set { - this.SetProperty(ref this._anonymousReport, value); + this.SetProperty(ref this.anonymousReport, value); this.UpdateEncodedReport(); } } - private bool _anonymousReport = true; + private bool anonymousReport = true; public bool CanSendByDM { - get => this._canSendByDm; - private set => this.SetProperty(ref this._canSendByDm, value); + get => this.canSendByDm; + private set => this.SetProperty(ref this.canSendByDm, value); } - private bool _canSendByDm; + private bool canSendByDm; public string EncodedReportForDM { - get => this._encodedReportForDM; - private set => this.SetProperty(ref this._encodedReportForDM, value); + get => this.encodedReportForDM; + private set => this.SetProperty(ref this.encodedReportForDM, value); } - private string _encodedReportForDM = ""; + private string encodedReportForDM = ""; private readonly Twitter? tw; private readonly string originalReportText; diff --git a/OpenTween/Setting/SettingBase.cs b/OpenTween/Setting/SettingBase.cs index 9b1f9bb86..f9cf25f6b 100644 --- a/OpenTween/Setting/SettingBase.cs +++ b/OpenTween/Setting/SettingBase.cs @@ -53,11 +53,11 @@ public abstract class SettingBase private static readonly object LockObj = new object(); - protected static T LoadSettings(string FileId) + protected static T LoadSettings(string fileId) { try { - var settingFilePath = GetSettingFilePath(FileId); + var settingFilePath = GetSettingFilePath(fileId); if (!File.Exists(settingFilePath)) { return new T(); @@ -82,7 +82,7 @@ protected static T LoadSettings(string FileId) Path.Combine( Application.StartupPath, ApplicationSettings.AssemblyName + "Backup1st"), - typeof(T).Name + FileId + ".xml"); + typeof(T).Name + fileId + ".xml"); if (File.Exists(backupFile)) { try @@ -93,7 +93,7 @@ protected static T LoadSettings(string FileId) fs.Position = 0; var xs = new XmlSerializer(typeof(T)); var instance = (T)xs.Deserialize(fs); - MessageBox.Show("File: " + GetSettingFilePath(FileId) + Environment.NewLine + "Use old setting file, because application can't read this setting file."); + MessageBox.Show("File: " + GetSettingFilePath(fileId) + Environment.NewLine + "Use old setting file, because application can't read this setting file."); return instance; } } @@ -101,7 +101,7 @@ protected static T LoadSettings(string FileId) { } } - MessageBox.Show("File: " + GetSettingFilePath(FileId) + Environment.NewLine + "Use default setting, because application can't read this setting file."); + MessageBox.Show("File: " + GetSettingFilePath(fileId) + Environment.NewLine + "Use default setting, because application can't read this setting file."); return new T(); } } @@ -170,10 +170,10 @@ protected static void SaveSettings(T instance, string fileId) MessageBox.Show("Can't write setting XML.(" + filePath + ")", "Save Settings", MessageBoxButtons.OK); } - protected static void SaveSettings(T Instance) - => SaveSettings(Instance, ""); + protected static void SaveSettings(T instance) + => SaveSettings(instance, ""); - public static string GetSettingFilePath(string FileId) - => Path.Combine(MyCommon.SettingPath, typeof(T).Name + FileId + ".xml"); + public static string GetSettingFilePath(string fileId) + => Path.Combine(MyCommon.SettingPath, typeof(T).Name + fileId + ".xml"); } } diff --git a/OpenTween/TabsDialog.cs b/OpenTween/TabsDialog.cs index 7f706eee4..4d74271ea 100644 --- a/OpenTween/TabsDialog.cs +++ b/OpenTween/TabsDialog.cs @@ -35,15 +35,15 @@ namespace OpenTween { public partial class TabsDialog : OTBaseForm { - private readonly TabInformations TabInfo; + private readonly TabInformations tabInfo; - private bool _MultiSelect = false; + private bool multiSelect = false; public bool MultiSelect { - get => this._MultiSelect; + get => this.multiSelect; set { - this._MultiSelect = value; + this.multiSelect = value; this.UpdateTabList(); } } @@ -61,7 +61,7 @@ public TabsDialog(TabInformations tabinformation) { this.InitializeComponent(); - this.TabInfo = tabinformation; + this.tabInfo = tabinformation; this.UpdateTabList(); } @@ -84,7 +84,7 @@ protected void UpdateTabList() }); } - var tabs = this.TabInfo.Tabs.Append(this.TabInfo.MuteTab); + var tabs = this.tabInfo.Tabs.Append(this.tabInfo.MuteTab); foreach (var tab in tabs.OfType()) { diff --git a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs index aea42814d..7a2113a15 100644 --- a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs +++ b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs @@ -38,12 +38,12 @@ namespace OpenTween.Thumbnail.Services { class ImgAzyobuziNet : IThumbnailService, IDisposable { - protected string[] ApiHosts = { + protected string[] apiHosts = { "https://img.azyobuzi.net/api/", "https://img.opentween.org/api/", }; - protected string[] ExcludedServiceNames = + protected string[] excludedServiceNames = { "Instagram", "Twitter", @@ -51,16 +51,16 @@ class ImgAzyobuziNet : IThumbnailService, IDisposable "Gyazo", }; - protected string? ApiBase; - protected IEnumerable? UrlRegex = null; - protected AsyncTimer UpdateTimer; + protected string? apiBase; + protected IEnumerable? urlRegex = null; + protected AsyncTimer updateTimer; protected HttpClient Http => this.localHttpClient ?? Networking.Http; private readonly HttpClient? localHttpClient; - private readonly object LockObj = new object(); + private readonly object lockObj = new object(); public ImgAzyobuziNet(bool autoupdate) : this(null, autoupdate) @@ -74,7 +74,7 @@ public ImgAzyobuziNet(HttpClient? http) public ImgAzyobuziNet(HttpClient? http, bool autoupdate) { - this.UpdateTimer = new AsyncTimer(this.LoadRegexAsync); + this.updateTimer = new AsyncTimer(this.LoadRegexAsync); this.AutoUpdate = autoupdate; this.Enabled = true; @@ -85,7 +85,7 @@ public ImgAzyobuziNet(HttpClient? http, bool autoupdate) public bool AutoUpdate { - get => this._AutoUpdate; + get => this.autoUpdate; set { if (value) @@ -93,10 +93,10 @@ public bool AutoUpdate else this.StopAutoUpdate(); - this._AutoUpdate = value; + this.autoUpdate = value; } } - private bool _AutoUpdate = false; + private bool autoUpdate = false; /// /// img.azyobizi.net によるサムネイル情報の取得を有効にするか @@ -109,14 +109,14 @@ public bool AutoUpdate public bool DisabledInDM { get; set; } protected void StartAutoUpdate() - => this.UpdateTimer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(30)); // 30分おきに更新 + => this.updateTimer.Change(TimeSpan.Zero, TimeSpan.FromMinutes(30)); // 30分おきに更新 protected void StopAutoUpdate() - => this.UpdateTimer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan); + => this.updateTimer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan); public async Task LoadRegexAsync() { - foreach (var host in this.ApiHosts) + foreach (var host in this.apiHosts) { try { @@ -134,10 +134,10 @@ public async Task LoadRegexAsync() } // どのサーバーも使用できない場合 - lock (this.LockObj) + lock (this.lockObj) { - this.UrlRegex = null; - this.ApiBase = null; + this.urlRegex = null; + this.apiBase = null; } } @@ -154,14 +154,14 @@ public async Task LoadRegexAsync(string apiBase) if (xElm.Element("error") != null) return false; - lock (this.LockObj) + lock (this.lockObj) { - this.UrlRegex = xElm.Elements("item") - .Where(x => !this.ExcludedServiceNames.Contains(x.Element("name").Value)) + this.urlRegex = xElm.Elements("item") + .Where(x => !this.excludedServiceNames.Contains(x.Element("name").Value)) .Select(e => new Regex(e.Element("regex").Value, RegexOptions.IgnoreCase)) .ToArray(); - this.ApiBase = apiBase; + this.apiBase = apiBase; } return true; @@ -195,20 +195,20 @@ protected virtual async Task FetchRegexAsync(string apiBase) if (this.DisabledInDM && post != null && post.IsDm) return null; - lock (this.LockObj) + lock (this.lockObj) { - if (this.UrlRegex == null) + if (this.urlRegex == null) return null; - foreach (var regex in this.UrlRegex) + foreach (var regex in this.urlRegex) { if (regex.IsMatch(url)) { return new ThumbnailInfo { MediaPageUrl = url, - ThumbnailImageUrl = this.ApiBase + "redirect?size=large&uri=" + Uri.EscapeDataString(url), - FullSizeImageUrl = this.ApiBase + "redirect?size=full&uri=" + Uri.EscapeDataString(url), + ThumbnailImageUrl = this.apiBase + "redirect?size=large&uri=" + Uri.EscapeDataString(url), + FullSizeImageUrl = this.apiBase + "redirect?size=full&uri=" + Uri.EscapeDataString(url), TooltipText = null, }; } @@ -221,6 +221,6 @@ protected virtual async Task FetchRegexAsync(string apiBase) } public virtual void Dispose() - => this.UpdateTimer.Dispose(); + => this.updateTimer.Dispose(); } } diff --git a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs index b74990307..d899076b8 100644 --- a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs @@ -40,12 +40,12 @@ namespace OpenTween.Thumbnail.Services /// class MetaThumbnailService : IThumbnailService { - protected static Regex[] MetaPatterns = + protected static Regex[] metaPatterns = { new Regex(".+?)[\"'] (content|value)=[\"'](?[^>]+?)[\"']"), new Regex("[^>]+?)[\"'] (name|property)=[\"'](?.+?)[\"']"), }; - protected static string[] PropertyNames = { "og:image", "twitter:image", "twitter:image:src" }; + protected static string[] defaultPropertyNames = { "og:image", "twitter:image", "twitter:image:src" }; protected HttpClient Http => this.localHttpClient ?? Networking.Http; @@ -74,7 +74,7 @@ public MetaThumbnailService(HttpClient? http, string urlPattern, string[]? propN { this.localHttpClient = http; this.regex = new Regex(urlPattern); - this.propertyNames = propNames ?? MetaThumbnailService.PropertyNames; + this.propertyNames = propNames ?? MetaThumbnailService.defaultPropertyNames; } public override async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) @@ -104,7 +104,7 @@ public MetaThumbnailService(HttpClient? http, string urlPattern, string[]? propN protected virtual string? GetThumbnailUrl(string html) { - foreach (var pattern in MetaThumbnailService.MetaPatterns) + foreach (var pattern in MetaThumbnailService.metaPatterns) { var matches = pattern.Matches(html); diff --git a/OpenTween/ToolStripAPIGauge.cs b/OpenTween/ToolStripAPIGauge.cs index 5f9ca82e5..4ac430573 100644 --- a/OpenTween/ToolStripAPIGauge.cs +++ b/OpenTween/ToolStripAPIGauge.cs @@ -53,16 +53,16 @@ public ToolStripAPIGauge() [RefreshProperties(RefreshProperties.Repaint)] public int GaugeHeight { - get => this._GaugeHeight; + get => this.gaugeHeight; set { - this._GaugeHeight = value; + this.gaugeHeight = value; this.UpdateGaugeBounds(); this.Invalidate(); } } - private int _GaugeHeight = 8; + private int gaugeHeight = 8; /// /// API 実行回数制限の値 @@ -70,10 +70,10 @@ public int GaugeHeight [Browsable(false)] public ApiLimit? ApiLimit { - get => this._ApiLimit; + get => this.apiLimit; private set { - this._ApiLimit = value; + this.apiLimit = value; this.UpdateRemainMinutes(); this.UpdateText(); @@ -81,7 +81,7 @@ private set this.Invalidate(); } } - private ApiLimit? _ApiLimit = null; + private ApiLimit? apiLimit = null; /// /// API エンドポイント名 @@ -89,37 +89,37 @@ private set [Browsable(false)] public string? ApiEndpoint { - get => this._ApiEndpoint; + get => this.apiEndpoint; set { if (MyCommon.IsNullOrEmpty(value)) { // リセット - this._ApiEndpoint = null; + this.apiEndpoint = null; this.ApiLimit = null; return; } var apiLimit = MyCommon.TwitterApiInfo.AccessLimit[value]; - if (this._ApiEndpoint != value) + if (this.apiEndpoint != value) { // ApiEndpointが変更されているので更新する - this._ApiEndpoint = value; + this.apiEndpoint = value; this.ApiLimit = apiLimit; } else { // ApiLimitが変更されていれば更新する - if (this._ApiLimit == null || - !this._ApiLimit.Equals(apiLimit)) + if (this.apiLimit == null || + !this.apiLimit.Equals(apiLimit)) { this.ApiLimit = apiLimit; } } } } - private string? _ApiEndpoint = null; + private string? apiEndpoint = null; [Browsable(false)] [EditorBrowsable(EditorBrowsableState.Never)] @@ -149,8 +149,8 @@ public string? ApiEndpoint protected virtual void UpdateRemainMinutes() { - if (this._ApiLimit != null) - this.remainMinutes = (this._ApiLimit.AccessLimitResetDate - DateTimeUtc.Now).TotalMinutes; + if (this.apiLimit != null) + this.remainMinutes = (this.apiLimit.AccessLimitResetDate - DateTimeUtc.Now).TotalMinutes; else this.remainMinutes = -1; } @@ -179,27 +179,27 @@ protected override void OnPaint(PaintEventArgs e) protected virtual void UpdateGaugeBounds() { - if (this._ApiLimit == null || this._GaugeHeight < 1) + if (this.apiLimit == null || this.gaugeHeight < 1) { this.ApiGaugeBounds = Rectangle.Empty; this.TimeGaugeBounds = Rectangle.Empty; return; } - var apiGaugeValue = (double)this._ApiLimit.AccessLimitRemain / this._ApiLimit.AccessLimitCount; + var apiGaugeValue = (double)this.apiLimit.AccessLimitRemain / this.apiLimit.AccessLimitCount; this.ApiGaugeBounds = new Rectangle( 0, - (this.Height - this._GaugeHeight * 2) / 2, + (this.Height - this.gaugeHeight * 2) / 2, (int)(this.Width * apiGaugeValue), - this._GaugeHeight + this.gaugeHeight ); var timeGaugeValue = this.remainMinutes >= 15 ? 1.00 : this.remainMinutes / 15; this.TimeGaugeBounds = new Rectangle( 0, - this.ApiGaugeBounds.Top + this._GaugeHeight, + this.ApiGaugeBounds.Top + this.gaugeHeight, (int)(this.Width * timeGaugeValue), - this._GaugeHeight + this.gaugeHeight ); } @@ -209,7 +209,7 @@ protected virtual void UpdateText() string maxCountText; string minuteText; - if (this._ApiLimit == null || this.remainMinutes < 0) + if (this.apiLimit == null || this.remainMinutes < 0) { remainCountText = "???"; maxCountText = "???"; @@ -217,12 +217,12 @@ protected virtual void UpdateText() } else { - remainCountText = this._ApiLimit.AccessLimitRemain.ToString(); - maxCountText = this._ApiLimit.AccessLimitCount.ToString(); + remainCountText = this.apiLimit.AccessLimitRemain.ToString(); + maxCountText = this.apiLimit.AccessLimitCount.ToString(); minuteText = Math.Ceiling(this.remainMinutes).ToString(); } - var endpointText = MyCommon.IsNullOrEmpty(this._ApiEndpoint) ? "unknown" : this._ApiEndpoint; + var endpointText = MyCommon.IsNullOrEmpty(this.apiEndpoint) ? "unknown" : this.apiEndpoint; var textFormat = "API {0}/{1}"; this.Text = string.Format(textFormat, remainCountText, maxCountText); diff --git a/OpenTween/ToolStripLabelHistory.cs b/OpenTween/ToolStripLabelHistory.cs index 52eebe465..1206520dc 100644 --- a/OpenTween/ToolStripLabelHistory.cs +++ b/OpenTween/ToolStripLabelHistory.cs @@ -72,7 +72,7 @@ public override string ToString() => this.Timestamp.ToLocalTime().ToString("T") + ": " + this.Summary; } - readonly LinkedList _logs; + private readonly LinkedList logs; const int MAXCNT = 20; @@ -82,10 +82,10 @@ public override string Text set { var oneline = value.Replace("\n", " "); - this._logs.AddLast(new LogEntry(DateTimeUtc.Now, oneline)); - while (this._logs.Count > MAXCNT) + this.logs.AddLast(new LogEntry(DateTimeUtc.Now, oneline)); + while (this.logs.Count > MAXCNT) { - this._logs.RemoveFirst(); + this.logs.RemoveFirst(); } base.Text = oneline; } @@ -96,7 +96,7 @@ public string TextHistory get { var sb = new StringBuilder(); - foreach (var e in this._logs) + foreach (var e in this.logs) { sb.AppendLine(e.ToString()); } @@ -105,6 +105,6 @@ public string TextHistory } public ToolStripLabelHistory() - => this._logs = new LinkedList(); + => this.logs = new LinkedList(); } } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index d9129b30f..2316bc415 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -66,44 +66,44 @@ public partial class TweenMain : OTBaseForm // 各種設定 /// 画面サイズ - private Size _mySize; + private Size mySize; /// 画面位置 - private Point _myLoc; + private Point myLoc; /// 区切り位置 - private int _mySpDis; + private int mySpDis; /// 発言欄区切り位置 - private int _mySpDis2; + private int mySpDis2; /// プレビュー区切り位置 - private int _mySpDis3; + private int mySpDis3; /// アイコンサイズ /// /// 現在は16、24、48の3種類。将来直接数字指定可能とする /// 注:24x24の場合に26と指定しているのはMSゴシック系フォントのための仕様 /// - private int _iconSz; + private int iconSz; - private bool _iconCol; // 1列表示の時true(48サイズのとき) + private bool iconCol; // 1列表示の時true(48サイズのとき) // 雑多なフラグ類 - private bool _initial; // true:起動時処理中 - private bool _initialLayout = true; - private bool _ignoreConfigSave; // true:起動時処理中 + private bool initial; // true:起動時処理中 + private bool initialLayout = true; + private bool ignoreConfigSave; // true:起動時処理中 /// タブドラッグ中フラグ(DoDragDropを実行するかの判定用) - private bool _tabDrag; + private bool tabDrag; - private TabPage? _beforeSelectedTab; // タブが削除されたときに前回選択されていたときのタブを選択する為に保持 - private Point _tabMouseDownPoint; + private TabPage? beforeSelectedTab; // タブが削除されたときに前回選択されていたときのタブを選択する為に保持 + private Point tabMouseDownPoint; /// 右クリックしたタブの名前(Tabコントロール機能不足対応) - private string? _rclickTabName; + private string? rclickTabName; - private readonly object _syncObject = new object(); // ロック用 + private readonly object syncObject = new object(); // ロック用 private const string DetailHtmlFormatHeaderMono = "" @@ -134,10 +134,10 @@ public partial class TweenMain : OTBaseForm private string detailHtmlFormatHeader = null!; private string detailHtmlFormatFooter = null!; - private bool _myStatusError = false; - private bool _myStatusOnline = false; + private bool myStatusError = false; + private bool myStatusOnline = false; private bool soundfileListup = false; - private FormWindowState _formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する + private FormWindowState formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する // twitter解析部 private readonly TwitterApi twitterApi = new TwitterApi(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); @@ -151,7 +151,7 @@ public partial class TweenMain : OTBaseForm /// 検索画面インスタンス internal SearchWordDialog SearchDialog = new SearchWordDialog(); - private readonly OpenURL UrlDialog = new OpenURL(); + private readonly OpenURL urlDialog = new OpenURL(); /// @id補助 public AtIdSupplement AtIdSupl = null!; @@ -164,105 +164,105 @@ public partial class TweenMain : OTBaseForm // 表示フォント、色、アイコン /// 未読用フォント - private Font _fntUnread = null!; + private Font fntUnread = null!; /// 未読用文字色 - private Color _clUnread; + private Color clUnread; /// 既読用フォント - private Font _fntReaded = null!; + private Font fntReaded = null!; /// 既読用文字色 - private Color _clReaded; + private Color clReaded; /// Fav用文字色 - private Color _clFav; + private Color clFav; /// 片思い用文字色 - private Color _clOWL; + private Color clOWL; /// Retweet用文字色 - private Color _clRetweet; + private Color clRetweet; /// 選択中の行用文字色 - private readonly Color _clHighLight = Color.FromKnownColor(KnownColor.HighlightText); + private readonly Color clHighLight = Color.FromKnownColor(KnownColor.HighlightText); /// 発言詳細部用フォント - private Font _fntDetail = null!; + private Font fntDetail = null!; /// 発言詳細部用色 - private Color _clDetail; + private Color clDetail; /// 発言詳細部用リンク文字色 - private Color _clDetailLink; + private Color clDetailLink; /// 発言詳細部用背景色 - private Color _clDetailBackcolor; + private Color clDetailBackcolor; /// 自分の発言用背景色 - private Color _clSelf; + private Color clSelf; /// 自分宛返信用背景色 - private Color _clAtSelf; + private Color clAtSelf; /// 選択発言者の他の発言用背景色 - private Color _clTarget; + private Color clTarget; /// 選択発言中の返信先用背景色 - private Color _clAtTarget; + private Color clAtTarget; /// 選択発言者への返信発言用背景色 - private Color _clAtFromTarget; + private Color clAtFromTarget; /// 選択発言の唯一@先 - private Color _clAtTo; + private Color clAtTo; /// リスト部通常発言背景色 - private Color _clListBackcolor; + private Color clListBackcolor; /// 入力欄背景色 - private Color _clInputBackcolor; + private Color clInputBackcolor; /// 入力欄文字色 - private Color _clInputFont; + private Color clInputFont; /// 入力欄フォント - private Font _fntInputFont = null!; + private Font fntInputFont = null!; /// アイコン画像リスト - private ImageCache IconCache = null!; + private ImageCache iconCache = null!; /// タスクトレイアイコン:通常時 (At.ico) - private Icon NIconAt = null!; + private Icon nIconAt = null!; /// タスクトレイアイコン:通信エラー時 (AtRed.ico) - private Icon NIconAtRed = null!; + private Icon nIconAtRed = null!; /// タスクトレイアイコン:オフライン時 (AtSmoke.ico) - private Icon NIconAtSmoke = null!; + private Icon nIconAtSmoke = null!; /// タスクトレイアイコン:更新中 (Refresh.ico) - private Icon[] NIconRefresh = new Icon[4]; + private Icon[] nIconRefresh = new Icon[4]; /// 未読のあるタブ用アイコン (Tab.ico) - private Icon TabIcon = null!; + private Icon tabIcon = null!; /// 画面左上のアイコン (Main.ico) - private Icon MainIcon = null!; + private Icon mainIcon = null!; - private Icon ReplyIcon = null!; - private Icon ReplyIconBlink = null!; + private Icon replyIcon = null!; + private Icon replyIconBlink = null!; - private readonly ImageList _listViewImageList = new ImageList(); // ListViewItemの高さ変更用 + private readonly ImageList listViewImageList = new ImageList(); // ListViewItemの高さ変更用 - private PostClass? _anchorPost; - private bool _anchorFlag; // true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画) + private PostClass? anchorPost; + private bool anchorFlag; // true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画) /// 発言履歴 - private readonly List _history = new List(); + private readonly List history = new List(); /// 発言履歴カレントインデックス - private int _hisIdx; + private int hisIdx; // 発言投稿時のAPI引数(発言編集時に設定。手書きreplyでは設定されない) @@ -270,36 +270,36 @@ public partial class TweenMain : OTBaseForm private (long StatusId, string ScreenName)? inReplyTo = null; // 時速表示用 - private readonly List _postTimestamps = new List(); - private readonly List _favTimestamps = new List(); + private readonly List postTimestamps = new List(); + private readonly List favTimestamps = new List(); // 以下DrawItem関連 - private readonly SolidBrush _brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight)); - private SolidBrush _brsBackColorMine = null!; - private SolidBrush _brsBackColorAt = null!; - private SolidBrush _brsBackColorYou = null!; - private SolidBrush _brsBackColorAtYou = null!; - private SolidBrush _brsBackColorAtFromTarget = null!; - private SolidBrush _brsBackColorAtTo = null!; - private SolidBrush _brsBackColorNone = null!; + private readonly SolidBrush brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight)); + private SolidBrush brsBackColorMine = null!; + private SolidBrush brsBackColorAt = null!; + private SolidBrush brsBackColorYou = null!; + private SolidBrush brsBackColorAtYou = null!; + private SolidBrush brsBackColorAtFromTarget = null!; + private SolidBrush brsBackColorAtTo = null!; + private SolidBrush brsBackColorNone = null!; /// Listにフォーカスないときの選択行の背景色 - private readonly SolidBrush _brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)); + private readonly SolidBrush brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)); private readonly StringFormat sfTab = new StringFormat(); ////////////////////////////////////////////////////////////////////////////////////////////////////////// - private TabInformations _statuses = null!; + private TabInformations statuses = null!; /// /// 現在表示している発言一覧の に対するキャッシュ /// /// /// キャッシュクリアのために null が代入されることがあるため、 - /// 使用する場合には に対して直接メソッド等を呼び出さずに + /// 使用する場合には に対して直接メソッド等を呼び出さずに /// 一旦ローカル変数に代入してから参照すること。 /// - private ListViewItemCache? _listItemCache = null; + private ListViewItemCache? listItemCache = null; internal class ListViewItemCache { @@ -347,20 +347,20 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ } } - private bool _isColumnChanged = false; + private bool isColumnChanged = false; private const int MAX_WORKER_THREADS = 20; private readonly SemaphoreSlim workerSemaphore = new SemaphoreSlim(MAX_WORKER_THREADS); private readonly CancellationTokenSource workerCts = new CancellationTokenSource(); private readonly IProgress workerProgress = null!; - private int UnreadCounter = -1; - private int UnreadAtCounter = -1; + private int unreadCounter = -1; + private int unreadAtCounter = -1; - private readonly string[] ColumnOrgText = new string[9]; - private readonly string[] ColumnText = new string[9]; + private readonly string[] columnOrgText = new string[9]; + private readonly string[] columnText = new string[9]; - private bool _DoFavRetweetFlags = false; + private bool doFavRetweetFlags = false; ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -402,13 +402,13 @@ public ReplyChain(long originalId, long inReplyToId, TabModel originalTab) private readonly Stack<(TabModel, PostClass?)> selectPostChains = new Stack<(TabModel, PostClass?)>(); public TabModel CurrentTab - => this._statuses.SelectedTab; + => this.statuses.SelectedTab; public string CurrentTabName - => this._statuses.SelectedTabName; + => this.statuses.SelectedTabName; public TabPage CurrentTabPage - => this.ListTab.TabPages[this._statuses.Tabs.IndexOf(this.CurrentTabName)]; + => this.ListTab.TabPages[this.statuses.Tabs.IndexOf(this.CurrentTabName)]; public DetailsListView CurrentListView => (DetailsListView)this.CurrentTabPage.Tag; @@ -471,43 +471,43 @@ protected override void Dispose(bool disposing) // 後始末 this.SearchDialog.Dispose(); - this.UrlDialog.Dispose(); - this.NIconAt?.Dispose(); - this.NIconAtRed?.Dispose(); - this.NIconAtSmoke?.Dispose(); - foreach (var iconRefresh in this.NIconRefresh) + this.urlDialog.Dispose(); + this.nIconAt?.Dispose(); + this.nIconAtRed?.Dispose(); + this.nIconAtSmoke?.Dispose(); + foreach (var iconRefresh in this.nIconRefresh) { iconRefresh?.Dispose(); } - this.TabIcon?.Dispose(); - this.MainIcon?.Dispose(); - this.ReplyIcon?.Dispose(); - this.ReplyIconBlink?.Dispose(); - this._listViewImageList.Dispose(); - this._brsHighLight.Dispose(); - this._brsBackColorMine?.Dispose(); - this._brsBackColorAt?.Dispose(); - this._brsBackColorYou?.Dispose(); - this._brsBackColorAtYou?.Dispose(); - this._brsBackColorAtFromTarget?.Dispose(); - this._brsBackColorAtTo?.Dispose(); - this._brsBackColorNone?.Dispose(); - this._brsDeactiveSelection?.Dispose(); + this.tabIcon?.Dispose(); + this.mainIcon?.Dispose(); + this.replyIcon?.Dispose(); + this.replyIconBlink?.Dispose(); + this.listViewImageList.Dispose(); + this.brsHighLight.Dispose(); + this.brsBackColorMine?.Dispose(); + this.brsBackColorAt?.Dispose(); + this.brsBackColorYou?.Dispose(); + this.brsBackColorAtYou?.Dispose(); + this.brsBackColorAtFromTarget?.Dispose(); + this.brsBackColorAtTo?.Dispose(); + this.brsBackColorNone?.Dispose(); + this.brsDeactiveSelection?.Dispose(); this.sfTab.Dispose(); this.timelineScheduler.Dispose(); this.workerCts.Cancel(); - if (this.IconCache != null) + if (this.iconCache != null) { - this.IconCache.CancelAsync(); - this.IconCache.Dispose(); + this.iconCache.CancelAsync(); + this.iconCache.Dispose(); } this.thumbnailTokenSource?.Dispose(); this.twitterApi.Dispose(); - this._hookGlobalHotkey.Dispose(); + this.hookGlobalHotkey.Dispose(); } // 終了時にRemoveHandlerしておかないとメモリリークする @@ -550,45 +550,45 @@ private void LoadIcons() // 読み込んだアイコンを設定 (不足するアイコンはデフォルトのものを設定) - this.MainIcon = iconMain ?? Properties.Resources.MIcon; - this.TabIcon = iconTab ?? Properties.Resources.TabIcon; - this.NIconAt = iconAt ?? iconMain ?? Properties.Resources.At; - this.NIconAtRed = iconAtRed ?? Properties.Resources.AtRed; - this.NIconAtSmoke = iconAtSmoke ?? Properties.Resources.AtSmoke; + this.mainIcon = iconMain ?? Properties.Resources.MIcon; + this.tabIcon = iconTab ?? Properties.Resources.TabIcon; + this.nIconAt = iconAt ?? iconMain ?? Properties.Resources.At; + this.nIconAtRed = iconAtRed ?? Properties.Resources.AtRed; + this.nIconAtSmoke = iconAtSmoke ?? Properties.Resources.AtSmoke; if (iconReply != null && iconReplyBlink != null) { - this.ReplyIcon = iconReply; - this.ReplyIconBlink = iconReplyBlink; + this.replyIcon = iconReply; + this.replyIconBlink = iconReplyBlink; } else { - this.ReplyIcon = iconReply ?? iconReplyBlink ?? Properties.Resources.Reply; - this.ReplyIconBlink = this.NIconAt; + this.replyIcon = iconReply ?? iconReplyBlink ?? Properties.Resources.Reply; + this.replyIconBlink = this.nIconAt; } if (iconRefresh1 == null) { - this.NIconRefresh = new[] { + this.nIconRefresh = new[] { Properties.Resources.Refresh, Properties.Resources.Refresh2, Properties.Resources.Refresh3, Properties.Resources.Refresh4, }; } else if (iconRefresh2 == null) { - this.NIconRefresh = new[] { iconRefresh1 }; + this.nIconRefresh = new[] { iconRefresh1 }; } else if (iconRefresh3 == null) { - this.NIconRefresh = new[] { iconRefresh1, iconRefresh2 }; + this.nIconRefresh = new[] { iconRefresh1, iconRefresh2 }; } else if (iconRefresh4 == null) { - this.NIconRefresh = new[] { iconRefresh1, iconRefresh2, iconRefresh3 }; + this.nIconRefresh = new[] { iconRefresh1, iconRefresh2, iconRefresh3 }; } else // iconRefresh1 から iconRefresh4 まで全て揃っている { - this.NIconRefresh = new[] { iconRefresh1, iconRefresh2, iconRefresh3, iconRefresh4 }; + this.nIconRefresh = new[] { iconRefresh1, iconRefresh2, iconRefresh3, iconRefresh4 }; } } @@ -614,7 +614,7 @@ private void InitColumns(ListView list, bool startup) ColumnHeader[]? columns = null; try { - if (this._iconCol) + if (this.iconCol) { columns = new[] { @@ -622,8 +622,8 @@ private void InitColumns(ListView list, bool startup) new ColumnHeader(), // 本文 }; - columns[0].Text = this.ColumnText[0]; - columns[1].Text = this.ColumnText[2]; + columns[0].Text = this.columnText[0]; + columns[1].Text = this.columnText[2]; if (startup) { @@ -660,7 +660,7 @@ private void InitColumns(ListView list, bool startup) }; foreach (var i in Enumerable.Range(0, columns.Length)) - columns[i].Text = this.ColumnText[i]; + columns[i].Text = this.columnText[i]; if (startup) { @@ -715,25 +715,25 @@ private void InitColumns(ListView list, bool startup) private void InitColumnText() { - this.ColumnText[0] = ""; - this.ColumnText[1] = Properties.Resources.AddNewTabText2; - this.ColumnText[2] = Properties.Resources.AddNewTabText3; - this.ColumnText[3] = Properties.Resources.AddNewTabText4_2; - this.ColumnText[4] = Properties.Resources.AddNewTabText5; - this.ColumnText[5] = ""; - this.ColumnText[6] = ""; - this.ColumnText[7] = "Source"; - - this.ColumnOrgText[0] = ""; - this.ColumnOrgText[1] = Properties.Resources.AddNewTabText2; - this.ColumnOrgText[2] = Properties.Resources.AddNewTabText3; - this.ColumnOrgText[3] = Properties.Resources.AddNewTabText4_2; - this.ColumnOrgText[4] = Properties.Resources.AddNewTabText5; - this.ColumnOrgText[5] = ""; - this.ColumnOrgText[6] = ""; - this.ColumnOrgText[7] = "Source"; - - var c = this._statuses.SortMode switch + this.columnText[0] = ""; + this.columnText[1] = Properties.Resources.AddNewTabText2; + this.columnText[2] = Properties.Resources.AddNewTabText3; + this.columnText[3] = Properties.Resources.AddNewTabText4_2; + this.columnText[4] = Properties.Resources.AddNewTabText5; + this.columnText[5] = ""; + this.columnText[6] = ""; + this.columnText[7] = "Source"; + + this.columnOrgText[0] = ""; + this.columnOrgText[1] = Properties.Resources.AddNewTabText2; + this.columnOrgText[2] = Properties.Resources.AddNewTabText3; + this.columnOrgText[3] = Properties.Resources.AddNewTabText4_2; + this.columnOrgText[4] = Properties.Resources.AddNewTabText5; + this.columnOrgText[5] = ""; + this.columnOrgText[6] = ""; + this.columnOrgText[7] = "Source"; + + var c = this.statuses.SortMode switch { ComparerMode.Nickname => 1, // ニックネーム ComparerMode.Data => 2, // 本文 @@ -743,30 +743,30 @@ private void InitColumnText() _ => 0, }; - if (this._iconCol) + if (this.iconCol) { - if (this._statuses.SortOrder == SortOrder.Descending) + if (this.statuses.SortOrder == SortOrder.Descending) { // U+25BE BLACK DOWN-POINTING SMALL TRIANGLE - this.ColumnText[2] = this.ColumnOrgText[2] + "▾"; + this.columnText[2] = this.columnOrgText[2] + "▾"; } else { // U+25B4 BLACK UP-POINTING SMALL TRIANGLE - this.ColumnText[2] = this.ColumnOrgText[2] + "▴"; + this.columnText[2] = this.columnOrgText[2] + "▴"; } } else { - if (this._statuses.SortOrder == SortOrder.Descending) + if (this.statuses.SortOrder == SortOrder.Descending) { // U+25BE BLACK DOWN-POINTING SMALL TRIANGLE - this.ColumnText[c] = this.ColumnOrgText[c] + "▾"; + this.columnText[c] = this.columnOrgText[c] + "▾"; } else { // U+25B4 BLACK UP-POINTING SMALL TRIANGLE - this.ColumnText[c] = this.ColumnOrgText[c] + "▴"; + this.columnText[c] = this.columnOrgText[c] + "▴"; } } } @@ -786,7 +786,7 @@ private void InitializeTraceFrag() private void TweenMain_Load(object sender, EventArgs e) { - this._ignoreConfigSave = true; + this.ignoreConfigSave = true; this.Visible = false; if (MyApplication.StartupOptions.ContainsKey("d")) @@ -799,13 +799,13 @@ private void TweenMain_Load(object sender, EventArgs e) Regex.CacheSize = 100; // 発言保持クラス - this._statuses = TabInformations.GetInstance(); + this.statuses = TabInformations.GetInstance(); // アイコン設定 this.LoadIcons(); - this.Icon = this.MainIcon; // メインフォーム(TweenMain) - this.NotifyIcon1.Icon = this.NIconAt; // タスクトレイ - this.TabImage.Images.Add(this.TabIcon); // タブ見出し + this.Icon = this.mainIcon; // メインフォーム(TweenMain) + this.NotifyIcon1.Icon = this.nIconAt; // タスクトレイ + this.TabImage.Images.Add(this.tabIcon); // タブ見出し // <<<<<<<<<設定関連>>>>>>>>> // 設定読み出し @@ -874,7 +874,7 @@ private void TweenMain_Load(object sender, EventArgs e) if (MyCommon.IsNullOrEmpty(SettingManager.Common.Token)) SettingManager.Common.UserName = ""; this.tw.Initialize(SettingManager.Common.Token, SettingManager.Common.TokenSecret, SettingManager.Common.UserName, SettingManager.Common.UserId); - this._initial = true; + this.initial = true; Networking.Initialize(); @@ -956,39 +956,39 @@ private void TweenMain_Load(object sender, EventArgs e) if (!MyCommon.IsNullOrEmpty(this.HashMgr.UseHash) && this.HashMgr.IsPermanent) this.HashStripSplitButton.Text = this.HashMgr.UseHash; // アイコンリスト作成 - this.IconCache = new ImageCache(); - this.tweetDetailsView.IconCache = this.IconCache; + this.iconCache = new ImageCache(); + this.tweetDetailsView.IconCache = this.iconCache; // フォント&文字色&背景色保持 - this._fntUnread = SettingManager.Local.FontUnread; - this._clUnread = SettingManager.Local.ColorUnread; - this._fntReaded = SettingManager.Local.FontRead; - this._clReaded = SettingManager.Local.ColorRead; - this._clFav = SettingManager.Local.ColorFav; - this._clOWL = SettingManager.Local.ColorOWL; - this._clRetweet = SettingManager.Local.ColorRetweet; - this._fntDetail = SettingManager.Local.FontDetail; - this._clDetail = SettingManager.Local.ColorDetail; - this._clDetailLink = SettingManager.Local.ColorDetailLink; - this._clDetailBackcolor = SettingManager.Local.ColorDetailBackcolor; - this._clSelf = SettingManager.Local.ColorSelf; - this._clAtSelf = SettingManager.Local.ColorAtSelf; - this._clTarget = SettingManager.Local.ColorTarget; - this._clAtTarget = SettingManager.Local.ColorAtTarget; - this._clAtFromTarget = SettingManager.Local.ColorAtFromTarget; - this._clAtTo = SettingManager.Local.ColorAtTo; - this._clListBackcolor = SettingManager.Local.ColorListBackcolor; - this._clInputBackcolor = SettingManager.Local.ColorInputBackcolor; - this._clInputFont = SettingManager.Local.ColorInputFont; - this._fntInputFont = SettingManager.Local.FontInputFont; - - this._brsBackColorMine = new SolidBrush(this._clSelf); - this._brsBackColorAt = new SolidBrush(this._clAtSelf); - this._brsBackColorYou = new SolidBrush(this._clTarget); - this._brsBackColorAtYou = new SolidBrush(this._clAtTarget); - this._brsBackColorAtFromTarget = new SolidBrush(this._clAtFromTarget); - this._brsBackColorAtTo = new SolidBrush(this._clAtTo); - this._brsBackColorNone = new SolidBrush(this._clListBackcolor); + this.fntUnread = SettingManager.Local.FontUnread; + this.clUnread = SettingManager.Local.ColorUnread; + this.fntReaded = SettingManager.Local.FontRead; + this.clReaded = SettingManager.Local.ColorRead; + this.clFav = SettingManager.Local.ColorFav; + this.clOWL = SettingManager.Local.ColorOWL; + this.clRetweet = SettingManager.Local.ColorRetweet; + this.fntDetail = SettingManager.Local.FontDetail; + this.clDetail = SettingManager.Local.ColorDetail; + this.clDetailLink = SettingManager.Local.ColorDetailLink; + this.clDetailBackcolor = SettingManager.Local.ColorDetailBackcolor; + this.clSelf = SettingManager.Local.ColorSelf; + this.clAtSelf = SettingManager.Local.ColorAtSelf; + this.clTarget = SettingManager.Local.ColorTarget; + this.clAtTarget = SettingManager.Local.ColorAtTarget; + this.clAtFromTarget = SettingManager.Local.ColorAtFromTarget; + this.clAtTo = SettingManager.Local.ColorAtTo; + this.clListBackcolor = SettingManager.Local.ColorListBackcolor; + this.clInputBackcolor = SettingManager.Local.ColorInputBackcolor; + this.clInputFont = SettingManager.Local.ColorInputFont; + this.fntInputFont = SettingManager.Local.FontInputFont; + + this.brsBackColorMine = new SolidBrush(this.clSelf); + this.brsBackColorAt = new SolidBrush(this.clAtSelf); + this.brsBackColorYou = new SolidBrush(this.clTarget); + this.brsBackColorAtYou = new SolidBrush(this.clAtTarget); + this.brsBackColorAtFromTarget = new SolidBrush(this.clAtFromTarget); + this.brsBackColorAtTo = new SolidBrush(this.clAtTo); + this.brsBackColorNone = new SolidBrush(this.clListBackcolor); // StringFormatオブジェクトへの事前設定 this.sfTab.Alignment = StringAlignment.Center; @@ -998,13 +998,13 @@ private void TweenMain_Load(object sender, EventArgs e) this.recommendedStatusFooter = " [TWNv" + Regex.Replace(MyCommon.FileVersion.Replace(".", ""), "^0*", "") + "]"; - this._history.Add(new StatusTextHistory()); - this._hisIdx = 0; + this.history.Add(new StatusTextHistory()); + this.hisIdx = 0; this.inReplyTo = null; // 各種ダイアログ設定 this.SearchDialog.Owner = this; - this.UrlDialog.Owner = this; + this.urlDialog.Owner = this; // 新着バルーン通知のチェック状態設定 this.NewPostPopMenuItem.Checked = SettingManager.Common.NewAllPop; @@ -1019,12 +1019,12 @@ private void TweenMain_Load(object sender, EventArgs e) // ウィンドウ設定 this.ClientSize = ScaleBy(configScaleFactor, SettingManager.Local.FormSize); - this._mySize = this.ClientSize; // サイズ保持(最小化・最大化されたまま終了した場合の対応用) - this._myLoc = SettingManager.Local.FormLocation; + this.mySize = this.ClientSize; // サイズ保持(最小化・最大化されたまま終了した場合の対応用) + this.myLoc = SettingManager.Local.FormLocation; // タイトルバー領域 if (this.WindowState != FormWindowState.Minimized) { - var tbarRect = new Rectangle(this._myLoc, new Size(this._mySize.Width, SystemInformation.CaptionHeight)); + var tbarRect = new Rectangle(this.myLoc, new Size(this.mySize.Width, SystemInformation.CaptionHeight)); var outOfScreen = true; if (Screen.AllScreens.Length == 1) // ハングするとの報告 { @@ -1038,28 +1038,28 @@ private void TweenMain_Load(object sender, EventArgs e) } if (outOfScreen) - this._myLoc = new Point(0, 0); + this.myLoc = new Point(0, 0); } - this.DesktopLocation = this._myLoc; + this.DesktopLocation = this.myLoc; } this.TopMost = SettingManager.Common.AlwaysTop; - this._mySpDis = ScaleBy(configScaleFactor.Height, SettingManager.Local.SplitterDistance); - this._mySpDis2 = ScaleBy(configScaleFactor.Height, SettingManager.Local.StatusTextHeight); + this.mySpDis = ScaleBy(configScaleFactor.Height, SettingManager.Local.SplitterDistance); + this.mySpDis2 = ScaleBy(configScaleFactor.Height, SettingManager.Local.StatusTextHeight); if (SettingManager.Local.PreviewDistance == -1) { - this._mySpDis3 = this._mySize.Width - ScaleBy(this.CurrentScaleFactor.Width, 150); - if (this._mySpDis3 < 1) this._mySpDis3 = ScaleBy(this.CurrentScaleFactor.Width, 50); - SettingManager.Local.PreviewDistance = this._mySpDis3; + this.mySpDis3 = this.mySize.Width - ScaleBy(this.CurrentScaleFactor.Width, 150); + if (this.mySpDis3 < 1) this.mySpDis3 = ScaleBy(this.CurrentScaleFactor.Width, 50); + SettingManager.Local.PreviewDistance = this.mySpDis3; } else { - this._mySpDis3 = ScaleBy(configScaleFactor.Width, SettingManager.Local.PreviewDistance); + this.mySpDis3 = ScaleBy(configScaleFactor.Width, SettingManager.Local.PreviewDistance); } this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound; this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound; // 入力欄 - this.StatusText.Font = this._fntInputFont; - this.StatusText.ForeColor = this._clInputFont; + this.StatusText.Font = this.fntInputFont; + this.StatusText.ForeColor = this.clInputFont; // SplitContainer2.Panel2MinSize を一行表示の入力欄の高さに合わせる (MS UI Gothic 12pt (96dpi) の場合は 19px) this.StatusText.Multiline = false; // SettingManager.Local.StatusMultiline の設定は後で反映される @@ -1121,19 +1121,19 @@ private void TweenMain_Load(object sender, EventArgs e) mode = ComparerMode.Source; break; } - this._statuses.SetSortMode(mode, sortOrder); + this.statuses.SetSortMode(mode, sortOrder); //////////////////////////////////////////////////////////////////////////////// this.ApplyListViewIconSize(SettingManager.Common.IconSize); // <<<<<<<<タブ関連>>>>>>> - foreach (var tab in this._statuses.Tabs) + foreach (var tab in this.statuses.Tabs) { if (!this.AddNewTab(tab, startup: true)) throw new TabException(Properties.Resources.TweenMain_LoadText1); } - this._statuses.SelectTab(this.ListTab.SelectedTab.Text); + this.statuses.SelectTab(this.ListTab.SelectedTab.Text); // タブの位置を調整する this.SetTabAlignment(); @@ -1165,7 +1165,7 @@ private void TweenMain_Load(object sender, EventArgs e) if ((SettingManager.Common.HotkeyModifier & Keys.LWin) == Keys.LWin) modKey |= HookGlobalHotkey.ModKeys.Win; - this._hookGlobalHotkey.RegisterOriginalHotkey(SettingManager.Common.HotkeyKey, SettingManager.Common.HotkeyValue, modKey); + this.hookGlobalHotkey.RegisterOriginalHotkey(SettingManager.Common.HotkeyKey, SettingManager.Common.HotkeyValue, modKey); } if (SettingManager.Common.IsUseNotifyGrowl) @@ -1206,7 +1206,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.TimerRefreshIcon.Interval = 200; this.TimerRefreshIcon.Enabled = false; - this._ignoreConfigSave = false; + this.ignoreConfigSave = false; this.TweenMain_Resize(this, EventArgs.Empty); if (saveRequired) this.SaveConfigsAll(false); @@ -1240,12 +1240,12 @@ private void InitDetailHtmlFormat() } this.detailHtmlFormatHeader = this.detailHtmlFormatHeader - .Replace("%FONT_FAMILY%", this._fntDetail.Name) - .Replace("%FONT_SIZE%", this._fntDetail.Size.ToString()) - .Replace("%FONT_COLOR%", $"{this._clDetail.R},{this._clDetail.G},{this._clDetail.B}") - .Replace("%LINK_COLOR%", $"{this._clDetailLink.R},{this._clDetailLink.G},{this._clDetailLink.B}") - .Replace("%BG_COLOR%", $"{this._clDetailBackcolor.R},{this._clDetailBackcolor.G},{this._clDetailBackcolor.B}") - .Replace("%BG_REPLY_COLOR%", $"{this._clAtTo.R}, {this._clAtTo.G}, {this._clAtTo.B}"); + .Replace("%FONT_FAMILY%", this.fntDetail.Name) + .Replace("%FONT_SIZE%", this.fntDetail.Size.ToString()) + .Replace("%FONT_COLOR%", $"{this.clDetail.R},{this.clDetail.G},{this.clDetail.B}") + .Replace("%LINK_COLOR%", $"{this.clDetailLink.R},{this.clDetailLink.G},{this.clDetailLink.B}") + .Replace("%BG_COLOR%", $"{this.clDetailBackcolor.R},{this.clDetailBackcolor.G},{this.clDetailBackcolor.B}") + .Replace("%BG_REPLY_COLOR%", $"{this.clAtTo.R}, {this.clAtTo.G}, {this.clAtTo.B}"); } private void ListTab_DrawItem(object sender, DrawItemEventArgs e) @@ -1253,7 +1253,7 @@ private void ListTab_DrawItem(object sender, DrawItemEventArgs e) string txt; try { - txt = this._statuses.Tabs[e.Index].TabName; + txt = this.statuses.Tabs[e.Index].TabName; } catch (Exception) { @@ -1268,7 +1268,7 @@ private void ListTab_DrawItem(object sender, DrawItemEventArgs e) Brush fore; try { - if (this._statuses.Tabs[txt].UnreadCount > 0) + if (this.statuses.Tabs[txt].UnreadCount > 0) fore = Brushes.Red; else fore = System.Drawing.SystemBrushes.ControlText; @@ -1341,13 +1341,13 @@ private void LoadConfig() filterTab.FilterModified = false; } - if (this._statuses.ContainsTab(tab.TabName)) - tab.TabName = this._statuses.MakeTabName("MyTab"); + if (this.statuses.ContainsTab(tab.TabName)) + tab.TabName = this.statuses.MakeTabName("MyTab"); - this._statuses.AddTab(tab); + this.statuses.AddTab(tab); } - this._statuses.AddDefaultTabs(); + this.statuses.AddDefaultTabs(); } private void TimerInterval_Changed(object sender, IntervalChangedEventArgs e) @@ -1412,7 +1412,7 @@ private void RefreshTimeline() // 更新確定 int addCount; - addCount = this._statuses.SubmitUpdate( + addCount = this.statuses.SubmitUpdate( out var soundFile, out var notifyPosts, out var newMentionOrDm, @@ -1421,7 +1421,7 @@ private void RefreshTimeline() if (MyCommon.EndingFlag) return; // リストに反映&選択状態復元 - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var tabPage = this.ListTab.TabPages[index]; var listView = (DetailsListView)tabPage.Tag; @@ -1455,7 +1455,7 @@ private void RefreshTimeline() { if (SettingManager.Common.TabIconDisp) { - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var tabPage = this.ListTab.TabPages[index]; if (tab.UnreadCount > 0 && tabPage.ImageIndex != 0) @@ -1524,9 +1524,9 @@ private ListViewScroll SaveListViewScroll(DetailsListView listView, TabModel tab private ScrollLockMode GetScrollLockMode(DetailsListView listView) { - if (this._statuses.SortMode == ComparerMode.Id) + if (this.statuses.SortMode == ComparerMode.Id) { - if (this._statuses.SortOrder == SortOrder.Ascending) + if (this.statuses.SortOrder == SortOrder.Ascending) { // Id昇順 if (this.ListLockMenuItem.Checked) @@ -1575,7 +1575,7 @@ private IReadOnlyDictionary SaveListViewSelection() { var listsDict = new Dictionary(); - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var listView = (DetailsListView)this.ListTab.TabPages[index].Tag; listsDict[tab.TabName] = this.SaveListViewSelection(listView, tab); @@ -1682,7 +1682,7 @@ private void RestoreListViewSelection(DetailsListView listView, TabModel tab, Li private bool BalloonRequired() { - if (this._initial) + if (this.initial) return false; if (NativeMethods.IsScreenSaverRunning()) @@ -1780,7 +1780,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo var bText = sb.ToString(); if (MyCommon.IsNullOrEmpty(bText)) return; - var image = this.IconCache.TryGetFromCache(post.ImageUrl); + var image = this.iconCache.TryGetFromCache(post.ImageUrl); this.gh.Notify(nt, post.StatusId.ToString(), title.ToString(), bText, image?.Image, post.ImageUrl); } } @@ -1848,7 +1848,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo } // サウンド再生 - if (!this._initial && SettingManager.Common.PlaySound && !MyCommon.IsNullOrEmpty(soundFile)) + if (!this.initial && SettingManager.Common.PlaySound && !MyCommon.IsNullOrEmpty(soundFile)) { try { @@ -1866,7 +1866,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo } // mentions新着時に画面ブリンク - if (!this._initial && SettingManager.Common.BlinkNewMentions && newMentions && Form.ActiveForm == null) + if (!this.initial && SettingManager.Common.BlinkNewMentions && newMentions && Form.ActiveForm == null) { NativeMethods.FlashMyWindow(this.Handle, 3); } @@ -1890,7 +1890,7 @@ private async void MyList_SelectedIndexChanged(object sender, EventArgs e) this.PushSelectPostChain(); var post = this.CurrentPost!; - this._statuses.SetReadAllTab(post.StatusId, read: true); + this.statuses.SetReadAllTab(post.StatusId, read: true); // キャッシュの書き換え this.ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色) @@ -1899,69 +1899,69 @@ private async void MyList_SelectedIndexChanged(object sender, EventArgs e) await this.selectionDebouncer.Call(); } - private void ChangeCacheStyleRead(bool Read, int Index) + private void ChangeCacheStyleRead(bool read, int index) { var tabInfo = this.CurrentTab; // Read:true=既読 false=未読 // 未読管理していなかったら既読として扱う if (!tabInfo.UnreadManage || - !SettingManager.Common.UnreadManage) Read = true; + !SettingManager.Common.UnreadManage) read = true; - var listCache = this._listItemCache; + var listCache = this.listItemCache; if (listCache == null) return; // キャッシュに含まれていないアイテムは対象外 - if (!listCache.TryGetValue(Index, out var itm, out var post)) + if (!listCache.TryGetValue(index, out var itm, out var post)) return; - this.ChangeItemStyleRead(Read, itm, post, (DetailsListView)listCache.TargetList); + this.ChangeItemStyleRead(read, itm, post, (DetailsListView)listCache.TargetList); } - private void ChangeItemStyleRead(bool Read, ListViewItem Item, PostClass Post, DetailsListView? DList) + private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post, DetailsListView? dList) { Font fnt; string star; // フォント - if (Read) + if (read) { - fnt = this._fntReaded; + fnt = this.fntReaded; star = ""; } else { - fnt = this._fntUnread; + fnt = this.fntUnread; star = "★"; } - if (Item.SubItems[5].Text != star) - Item.SubItems[5].Text = star; + if (item.SubItems[5].Text != star) + item.SubItems[5].Text = star; // 文字色 Color cl; - if (Post.IsFav) - cl = this._clFav; - else if (Post.RetweetedId != null) - cl = this._clRetweet; - else if (Post.IsOwl && (Post.IsDm || SettingManager.Common.OneWayLove)) - cl = this._clOWL; - else if (Read || !SettingManager.Common.UseUnreadStyle) - cl = this._clReaded; + if (post.IsFav) + cl = this.clFav; + else if (post.RetweetedId != null) + cl = this.clRetweet; + else if (post.IsOwl && (post.IsDm || SettingManager.Common.OneWayLove)) + cl = this.clOWL; + else if (read || !SettingManager.Common.UseUnreadStyle) + cl = this.clReaded; else - cl = this._clUnread; + cl = this.clUnread; - if (DList == null || Item.Index == -1) + if (dList == null || item.Index == -1) { - Item.ForeColor = cl; + item.ForeColor = cl; if (SettingManager.Common.UseUnreadStyle) - Item.Font = fnt; + item.Font = fnt; } else { - DList.Update(); + dList.Update(); if (SettingManager.Common.UseUnreadStyle) - DList.ChangeItemFontAndColor(Item, cl, fnt); + dList.ChangeItemFontAndColor(item, cl, fnt); else - DList.ChangeItemForeColor(Item, cl); + dList.ChangeItemForeColor(item, cl); } } @@ -1969,15 +1969,15 @@ private void ColorizeList() { // Index:更新対象のListviewItem.Index。Colorを返す。 // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - PostClass? _post; - if (this._anchorFlag) - _post = this._anchorPost; + PostClass? post; + if (this.anchorFlag) + post = this.anchorPost; else - _post = this.CurrentPost; + post = this.CurrentPost; - if (_post == null) return; + if (post == null) return; - var listCache = this._listItemCache; + var listCache = this.listItemCache; if (listCache == null) return; @@ -1988,53 +1988,53 @@ private void ColorizeList() foreach (var (listViewItem, cachedPost) in listCache.Cache) { - var backColor = this.JudgeColor(_post, cachedPost); + var backColor = this.JudgeColor(post, cachedPost); listView.ChangeItemBackColor(listViewItem, backColor); } } - private void ColorizeList(ListViewItem Item, PostClass post) + private void ColorizeList(ListViewItem item, PostClass post) { // Index:更新対象のListviewItem.Index。Colorを返す。 // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - PostClass? _post; - if (this._anchorFlag) - _post = this._anchorPost; + PostClass? basePost; + if (this.anchorFlag) + basePost = this.anchorPost; else - _post = this.CurrentPost; + basePost = this.CurrentPost; - if (_post == null) return; + if (basePost == null) return; - if (Item.Index == -1) - Item.BackColor = this.JudgeColor(_post, post); + if (item.Index == -1) + item.BackColor = this.JudgeColor(basePost, post); else - this.CurrentListView.ChangeItemBackColor(Item, this.JudgeColor(_post, post)); + this.CurrentListView.ChangeItemBackColor(item, this.JudgeColor(basePost, post)); } - private Color JudgeColor(PostClass BasePost, PostClass TargetPost) + private Color JudgeColor(PostClass basePost, PostClass targetPost) { Color cl; - if (TargetPost.StatusId == BasePost.InReplyToStatusId) + if (targetPost.StatusId == basePost.InReplyToStatusId) // @先 - cl = this._clAtTo; - else if (TargetPost.IsMe) + cl = this.clAtTo; + else if (targetPost.IsMe) // 自分=発言者 - cl = this._clSelf; - else if (TargetPost.IsReply) + cl = this.clSelf; + else if (targetPost.IsReply) // 自分宛返信 - cl = this._clAtSelf; - else if (BasePost.ReplyToList.Any(x => x.UserId == TargetPost.UserId)) + cl = this.clAtSelf; + else if (basePost.ReplyToList.Any(x => x.UserId == targetPost.UserId)) // 返信先 - cl = this._clAtFromTarget; - else if (TargetPost.ReplyToList.Any(x => x.UserId == BasePost.UserId)) + cl = this.clAtFromTarget; + else if (targetPost.ReplyToList.Any(x => x.UserId == basePost.UserId)) // その人への返信 - cl = this._clAtTarget; - else if (TargetPost.UserId == BasePost.UserId) + cl = this.clAtTarget; + else if (targetPost.UserId == basePost.UserId) // 発言者 - cl = this._clTarget; + cl = this.clTarget; else // その他 - cl = this._clListBackcolor; + cl = this.clListBackcolor; return cl; } @@ -2042,13 +2042,13 @@ private Color JudgeColor(PostClass BasePost, PostClass TargetPost) private void StatusTextHistoryBack() { if (!string.IsNullOrWhiteSpace(this.StatusText.Text)) - this._history[this._hisIdx] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo); + this.history[this.hisIdx] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo); - this._hisIdx -= 1; - if (this._hisIdx < 0) - this._hisIdx = 0; + this.hisIdx -= 1; + if (this.hisIdx < 0) + this.hisIdx = 0; - var historyItem = this._history[this._hisIdx]; + var historyItem = this.history[this.hisIdx]; this.inReplyTo = historyItem.InReplyTo; this.StatusText.Text = historyItem.Status; this.StatusText.SelectionStart = this.StatusText.Text.Length; @@ -2057,13 +2057,13 @@ private void StatusTextHistoryBack() private void StatusTextHistoryForward() { if (!string.IsNullOrWhiteSpace(this.StatusText.Text)) - this._history[this._hisIdx] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo); + this.history[this.hisIdx] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo); - this._hisIdx += 1; - if (this._hisIdx > this._history.Count - 1) - this._hisIdx = this._history.Count - 1; + this.hisIdx += 1; + if (this.hisIdx > this.history.Count - 1) + this.hisIdx = this.history.Count - 1; - var historyItem = this._history[this._hisIdx]; + var historyItem = this.history[this.hisIdx]; this.inReplyTo = historyItem.InReplyTo; this.StatusText.Text = historyItem.Status; this.StatusText.SelectionStart = this.StatusText.Text.Length; @@ -2107,7 +2107,7 @@ private async void PostButton_Click(object sender, EventArgs e) return; } - this._history[this._history.Count - 1] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo); + this.history[this.history.Count - 1] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo); if (SettingManager.Common.Nicoms) { @@ -2137,7 +2137,7 @@ private async void PostButton_Click(object sender, EventArgs e) // リプライ先がセットされていても autoPopulatedUserIds が空の場合は auto_populate_reply_metadata を有効にしない // (非公式 RT の場合など) - var replyToPost = this.inReplyTo != null ? this._statuses[this.inReplyTo.Value.StatusId] : null; + var replyToPost = this.inReplyTo != null ? this.statuses[this.inReplyTo.Value.StatusId] : null; if (replyToPost != null && autoPopulatedUserIds.Length != 0) { status.AutoPopulateReplyMetadata = true; @@ -2169,8 +2169,8 @@ private async void PostButton_Click(object sender, EventArgs e) this.inReplyTo = null; this.StatusText.Text = ""; - this._history.Add(new StatusTextHistory()); - this._hisIdx = this._history.Count - 1; + this.history.Add(new StatusTextHistory()); + this.hisIdx = this.history.Count - 1; if (!SettingManager.Common.FocusLockToStatusText) this.CurrentListView.Focus(); this.urlUndoBuffer = null; @@ -2202,8 +2202,8 @@ private void TweenMain_FormClosing(object sender, FormClosingEventArgs e) } else { - this._hookGlobalHotkey.UnregisterAllOriginalHotkey(); - this._ignoreConfigSave = true; + this.hookGlobalHotkey.UnregisterAllOriginalHotkey(); + this.ignoreConfigSave = true; MyCommon.EndingFlag = true; this.timelineScheduler.Enabled = false; this.TimerRefreshIcon.Enabled = false; @@ -2250,7 +2250,7 @@ private Task RefreshTabAsync(bool backward) where T : TabModel { var loadTasks = - from tab in this._statuses.GetTabsByType() + from tab in this.statuses.GetTabsByType() select this.RefreshTabAsync(tab, backward); return Task.WhenAll(loadTasks); @@ -2268,11 +2268,11 @@ private async Task RefreshTabAsync(TabModel tab, bool backward) try { this.RefreshTasktrayIcon(); - await Task.Run(() => tab.RefreshAsync(this.tw, backward, this._initial, this.workerProgress)); + await Task.Run(() => tab.RefreshAsync(this.tw, backward, this.initial, this.workerProgress)); } catch (WebApiException ex) { - this._myStatusError = true; + this.myStatusError = true; var tabType = tab switch { HomeTabModel _ => "GetTimeline", @@ -2307,7 +2307,7 @@ private async Task FavAddAsync(long statusId, TabModel tab) } catch (WebApiException ex) { - this._myStatusError = true; + this.myStatusError = true; this.StatusLabel.Text = $"Err:{ex.Message}(PostFavAdd)"; } finally @@ -2357,19 +2357,19 @@ await this.twitterApi.FavoritesCreate(post.RetweetedId ?? post.StatusId) throw new WebApiException("NG(Restricted?)"); } - this._favTimestamps.Add(DateTimeUtc.Now); + this.favTimestamps.Add(DateTimeUtc.Now); // TLでも取得済みならfav反映 - if (this._statuses.Posts.TryGetValue(statusId, out var postTl)) + if (this.statuses.Posts.TryGetValue(statusId, out var postTl)) { postTl.IsFav = true; - var favTab = this._statuses.FavoriteTab; + var favTab = this.statuses.FavoriteTab; favTab.AddPostQueue(postTl); } // 検索,リスト,UserTimeline,Relatedの各タブに反映 - foreach (var tb in this._statuses.GetTabsInnerStorageType()) + foreach (var tb in this.statuses.GetTabsInnerStorageType()) { if (tb.Contains(statusId)) tb.Posts[statusId].IsFav = true; @@ -2385,13 +2385,13 @@ await this.twitterApi.FavoritesCreate(post.RetweetedId ?? post.StatusId) // 時速表示用 var oneHour = DateTimeUtc.Now - TimeSpan.FromHours(1); - foreach (var i in MyCommon.CountDown(this._favTimestamps.Count - 1, 0)) + foreach (var i in MyCommon.CountDown(this.favTimestamps.Count - 1, 0)) { - if (this._favTimestamps[i] < oneHour) - this._favTimestamps.RemoveAt(i); + if (this.favTimestamps[i] < oneHour) + this.favTimestamps.RemoveAt(i); } - this._statuses.DistributePosts(); + this.statuses.DistributePosts(); }); if (ct.IsCancellationRequested) @@ -2427,7 +2427,7 @@ private async Task FavRemoveAsync(IReadOnlyList statusIds, TabModel tab) } catch (WebApiException ex) { - this._myStatusError = true; + this.myStatusError = true; this.StatusLabel.Text = $"Err:{ex.Message}(PostFavRemove)"; } finally @@ -2477,11 +2477,11 @@ await this.twitterApi.FavoritesDestroy(post.RetweetedId ?? post.StatusId) successIds.Add(statusId); post.IsFav = false; // リスト再描画必要 - if (this._statuses.Posts.TryGetValue(statusId, out var tabinfoPost)) + if (this.statuses.Posts.TryGetValue(statusId, out var tabinfoPost)) tabinfoPost.IsFav = false; // 検索,リスト,UserTimeline,Relatedの各タブに反映 - foreach (var tb in this._statuses.GetTabsInnerStorageType()) + foreach (var tb in this.statuses.GetTabsInnerStorageType()) { if (tb.Contains(statusId)) tb.Posts[statusId].IsFav = false; @@ -2492,7 +2492,7 @@ await this.twitterApi.FavoritesDestroy(post.RetweetedId ?? post.StatusId) if (ct.IsCancellationRequested) return; - var favTab = this._statuses.FavoriteTab; + var favTab = this.statuses.FavoriteTab; foreach (var statusId in successIds) { // ツイートが削除された訳ではないので IsDeleted はセットしない @@ -2542,7 +2542,7 @@ private async Task PostMessageAsync(PostStatusParams postParams, IMediaUploadSer } catch (WebApiException ex) { - this._myStatusError = true; + this.myStatusError = true; this.StatusLabel.Text = $"Err:{ex.Message}(PostMessage)"; } finally @@ -2592,14 +2592,14 @@ await Task.Run(async () => // 処理は中断せずエラーの表示のみ行う errMsg = $"Err:{ex.Message}(PostMessage)"; p.Report(errMsg); - this._myStatusError = true; + this.myStatusError = true; } catch (UnauthorizedAccessException ex) { // アップロード対象のファイルが開けなかった場合など errMsg = $"Err:{ex.Message}(PostMessage)"; p.Report(errMsg); - this._myStatusError = true; + this.myStatusError = true; } finally { @@ -2644,13 +2644,13 @@ await Task.Run(async () => return; } - this._postTimestamps.Add(DateTimeUtc.Now); + this.postTimestamps.Add(DateTimeUtc.Now); var oneHour = DateTimeUtc.Now - TimeSpan.FromHours(1); - foreach (var i in MyCommon.CountDown(this._postTimestamps.Count - 1, 0)) + foreach (var i in MyCommon.CountDown(this.postTimestamps.Count - 1, 0)) { - if (this._postTimestamps[i] < oneHour) - this._postTimestamps.RemoveAt(i); + if (this.postTimestamps[i] < oneHour) + this.postTimestamps.RemoveAt(i); } if (!this.HashMgr.IsPermanent && !MyCommon.IsNullOrEmpty(this.HashMgr.UseHash)) @@ -2670,8 +2670,8 @@ await Task.Run(async () => { if (post != null) { - this._statuses.AddPost(post); - this._statuses.DistributePosts(); + this.statuses.AddPost(post); + this.statuses.DistributePosts(); } this.RefreshTimeline(); } @@ -2690,7 +2690,7 @@ private async Task RetweetAsync(IReadOnlyList statusIds) } catch (WebApiException ex) { - this._myStatusError = true; + this.myStatusError = true; this.StatusLabel.Text = $"Err:{ex.Message}(PostRetweet)"; } finally @@ -2711,7 +2711,7 @@ private async Task RetweetAsyncInternal(IProgress p, CancellationToken c if (!SettingManager.Common.UnreadManage) read = true; else - read = this._initial && SettingManager.Common.Read; + read = this.initial && SettingManager.Common.Read; p.Report("Posting..."); @@ -2731,24 +2731,24 @@ await Task.Run(async () => p.Report(Properties.Resources.PostWorker_RunWorkerCompletedText4); - this._postTimestamps.Add(DateTimeUtc.Now); + this.postTimestamps.Add(DateTimeUtc.Now); var oneHour = DateTimeUtc.Now - TimeSpan.FromHours(1); - foreach (var i in MyCommon.CountDown(this._postTimestamps.Count - 1, 0)) + foreach (var i in MyCommon.CountDown(this.postTimestamps.Count - 1, 0)) { - if (this._postTimestamps[i] < oneHour) - this._postTimestamps.RemoveAt(i); + if (this.postTimestamps[i] < oneHour) + this.postTimestamps.RemoveAt(i); } // 自分のRTはTLの更新では取得できない場合があるので、 // 投稿時取得の有無に関わらず追加しておく - posts.ForEach(post => this._statuses.AddPost(post)); + posts.ForEach(post => this.statuses.AddPost(post)); if (SettingManager.Common.PostAndGet) await this.RefreshTabAsync(); else { - this._statuses.DistributePosts(); + this.statuses.DistributePosts(); this.RefreshTimeline(); } } @@ -2878,7 +2878,7 @@ private void NotifyIcon1_MouseClick(object sender, MouseEventArgs e) this.Visible = true; if (this.WindowState == FormWindowState.Minimized) { - this.WindowState = this._formWindowState; + this.WindowState = this.formWindowState; } this.Activate(); this.BringToFront(); @@ -2931,7 +2931,7 @@ private async void FavoriteRetweetMenuItem_Click(object sender, EventArgs e) private async void FavoriteRetweetUnofficialMenuItem_Click(object sender, EventArgs e) => await this.FavoritesRetweetUnofficial(); - private async Task FavoriteChange(bool FavAdd, bool multiFavoriteChangeDialogEnable = true) + private async Task FavoriteChange(bool favAdd, bool multiFavoriteChangeDialogEnable = true) { var tab = this.CurrentTab; var posts = tab.SelectedPosts; @@ -2942,12 +2942,12 @@ private async Task FavoriteChange(bool FavAdd, bool multiFavoriteChangeDialogEna if (posts.Length > 1) { - if (FavAdd) + if (favAdd) { // 複数ツイートの一括ふぁぼは禁止 // https://support.twitter.com/articles/76915#favoriting MessageBox.Show(string.Format(Properties.Resources.FavoriteLimitCountText, 1)); - this._DoFavRetweetFlags = false; + this.doFavRetweetFlags = false; return; } else @@ -2966,7 +2966,7 @@ private async Task FavoriteChange(bool FavAdd, bool multiFavoriteChangeDialogEna } } - if (FavAdd) + if (favAdd) { var selectedPost = posts.Single(); if (selectedPost.IsFav) @@ -2991,16 +2991,16 @@ private async Task FavoriteChange(bool FavAdd, bool multiFavoriteChangeDialogEna } } - private PostClass GetCurTabPost(int Index) + private PostClass GetCurTabPost(int index) { - var listCache = this._listItemCache; + var listCache = this.listItemCache; if (listCache != null) { - if (listCache.TryGetValue(Index, out _, out var post)) + if (listCache.TryGetValue(index, out _, out var post)) return post; } - return this.CurrentTab[Index]; + return this.CurrentTab[index]; } private async void MoveToHomeToolStripMenuItem_Click(object sender, EventArgs e) @@ -3021,14 +3021,14 @@ private async void MoveToFavToolStripMenuItem_Click(object sender, EventArgs e) private void TweenMain_ClientSizeChanged(object sender, EventArgs e) { - if ((!this._initialLayout) && this.Visible) + if ((!this.initialLayout) && this.Visible) { if (this.WindowState == FormWindowState.Normal) { - this._mySize = this.ClientSize; - this._mySpDis = this.SplitContainer1.SplitterDistance; - this._mySpDis3 = this.SplitContainer3.SplitterDistance; - if (this.StatusText.Multiline) this._mySpDis2 = this.StatusText.Height; + this.mySize = this.ClientSize; + this.mySpDis = this.SplitContainer1.SplitterDistance; + this.mySpDis3 = this.SplitContainer3.SplitterDistance; + if (this.StatusText.Multiline) this.mySpDis2 = this.StatusText.Height; this.MarkSettingLocalModified(); } } @@ -3050,7 +3050,7 @@ private void MyList_ColumnClick(object sender, ColumnClickEventArgs e) /// ソートを行う ComparerMode。null であればソートを行わない private ComparerMode? GetComparerModeByColumnIndex(int columnIndex) { - if (this._iconCol) + if (this.iconCol) return ComparerMode.Id; return columnIndex switch @@ -3109,20 +3109,20 @@ private void SetSortColumn(ComparerMode sortColumn) if (SettingManager.Common.SortOrderLock) return; - this._statuses.ToggleSortOrder(sortColumn); + this.statuses.ToggleSortOrder(sortColumn); this.InitColumnText(); var list = this.CurrentListView; - if (this._iconCol) + if (this.iconCol) { - list.Columns[0].Text = this.ColumnText[0]; - list.Columns[1].Text = this.ColumnText[2]; + list.Columns[0].Text = this.columnText[0]; + list.Columns[1].Text = this.columnText[2]; } else { for (var i = 0; i <= 7; i++) { - list.Columns[i].Text = this.ColumnText[i]; + list.Columns[i].Text = this.columnText[i]; } } @@ -3146,9 +3146,9 @@ private void SetSortColumn(ComparerMode sortColumn) private void TweenMain_LocationChanged(object sender, EventArgs e) { - if (this.WindowState == FormWindowState.Normal && !this._initialLayout) + if (this.WindowState == FormWindowState.Normal && !this.initialLayout) { - this._myLoc = this.DesktopLocation; + this.myLoc = this.DesktopLocation; this.MarkSettingLocalModified(); } } @@ -3328,7 +3328,7 @@ await this.twitterApi.StatusesDestroy(post.StatusId) continue; } - this._statuses.RemovePostFromAllTabs(post.StatusId, setIsDeleted: true); + this.statuses.RemovePostFromAllTabs(post.StatusId, setIsDeleted: true); } if (lastException == null) @@ -3338,7 +3338,7 @@ await this.twitterApi.StatusesDestroy(post.StatusId) this.PurgeListViewItemCache(); - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var tabPage = this.ListTab.TabPages[index]; var listView = (DetailsListView)tabPage.Tag; @@ -3388,7 +3388,7 @@ private void ReadedStripMenuItem_Click(object sender, EventArgs e) var tab = this.CurrentTab; foreach (var statusId in tab.SelectedStatusIds) { - this._statuses.SetReadAllTab(statusId, read: true); + this.statuses.SetReadAllTab(statusId, read: true); var idx = tab.IndexOf(statusId); this.ChangeCacheStyleRead(true, idx); } @@ -3396,7 +3396,7 @@ private void ReadedStripMenuItem_Click(object sender, EventArgs e) } if (SettingManager.Common.TabIconDisp) { - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { if (tab.UnreadCount == 0) { @@ -3416,7 +3416,7 @@ private void UnreadStripMenuItem_Click(object sender, EventArgs e) var tab = this.CurrentTab; foreach (var statusId in tab.SelectedStatusIds) { - this._statuses.SetReadAllTab(statusId, read: false); + this.statuses.SetReadAllTab(statusId, read: false); var idx = tab.IndexOf(statusId); this.ChangeCacheStyleRead(false, idx); } @@ -3424,7 +3424,7 @@ private void UnreadStripMenuItem_Click(object sender, EventArgs e) } if (SettingManager.Common.TabIconDisp) { - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { if (tab.UnreadCount > 0) { @@ -3451,7 +3451,7 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) var result = DialogResult.Abort; using var settingDialog = new AppendSettingDialog(); - settingDialog.Icon = this.MainIcon; + settingDialog.Icon = this.mainIcon; settingDialog.Owner = this; settingDialog.ShowInTaskbar = showTaskbarIcon; settingDialog.IntervalChanged += this.TimerInterval_Changed; @@ -3472,7 +3472,7 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) if (result == DialogResult.OK) { - lock (this._syncObject) + lock (this.syncObject) { settingDialog.SaveConfig(SettingManager.Common, SettingManager.Local); } @@ -3490,7 +3490,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) if (this.ShowSettingDialog() == DialogResult.OK) { - lock (this._syncObject) + lock (this.syncObject) { this.tw.RestrictFavCheck = SettingManager.Common.RestrictFavCheck; this.tw.ReadOwnPost = SettingManager.Common.ReadOwnPost; @@ -3575,47 +3575,47 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) this.NotifyFileMenuItem.Checked = SettingManager.Common.NewAllPop; this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound; this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound; - this._fntUnread = SettingManager.Local.FontUnread; - this._clUnread = SettingManager.Local.ColorUnread; - this._fntReaded = SettingManager.Local.FontRead; - this._clReaded = SettingManager.Local.ColorRead; - this._clFav = SettingManager.Local.ColorFav; - this._clOWL = SettingManager.Local.ColorOWL; - this._clRetweet = SettingManager.Local.ColorRetweet; - this._fntDetail = SettingManager.Local.FontDetail; - this._clDetail = SettingManager.Local.ColorDetail; - this._clDetailLink = SettingManager.Local.ColorDetailLink; - this._clDetailBackcolor = SettingManager.Local.ColorDetailBackcolor; - this._clSelf = SettingManager.Local.ColorSelf; - this._clAtSelf = SettingManager.Local.ColorAtSelf; - this._clTarget = SettingManager.Local.ColorTarget; - this._clAtTarget = SettingManager.Local.ColorAtTarget; - this._clAtFromTarget = SettingManager.Local.ColorAtFromTarget; - this._clAtTo = SettingManager.Local.ColorAtTo; - this._clListBackcolor = SettingManager.Local.ColorListBackcolor; - this._clInputBackcolor = SettingManager.Local.ColorInputBackcolor; - this._clInputFont = SettingManager.Local.ColorInputFont; - this._fntInputFont = SettingManager.Local.FontInputFont; - this._brsBackColorMine.Dispose(); - this._brsBackColorAt.Dispose(); - this._brsBackColorYou.Dispose(); - this._brsBackColorAtYou.Dispose(); - this._brsBackColorAtFromTarget.Dispose(); - this._brsBackColorAtTo.Dispose(); - this._brsBackColorNone.Dispose(); - this._brsBackColorMine = new SolidBrush(this._clSelf); - this._brsBackColorAt = new SolidBrush(this._clAtSelf); - this._brsBackColorYou = new SolidBrush(this._clTarget); - this._brsBackColorAtYou = new SolidBrush(this._clAtTarget); - this._brsBackColorAtFromTarget = new SolidBrush(this._clAtFromTarget); - this._brsBackColorAtTo = new SolidBrush(this._clAtTo); - this._brsBackColorNone = new SolidBrush(this._clListBackcolor); + this.fntUnread = SettingManager.Local.FontUnread; + this.clUnread = SettingManager.Local.ColorUnread; + this.fntReaded = SettingManager.Local.FontRead; + this.clReaded = SettingManager.Local.ColorRead; + this.clFav = SettingManager.Local.ColorFav; + this.clOWL = SettingManager.Local.ColorOWL; + this.clRetweet = SettingManager.Local.ColorRetweet; + this.fntDetail = SettingManager.Local.FontDetail; + this.clDetail = SettingManager.Local.ColorDetail; + this.clDetailLink = SettingManager.Local.ColorDetailLink; + this.clDetailBackcolor = SettingManager.Local.ColorDetailBackcolor; + this.clSelf = SettingManager.Local.ColorSelf; + this.clAtSelf = SettingManager.Local.ColorAtSelf; + this.clTarget = SettingManager.Local.ColorTarget; + this.clAtTarget = SettingManager.Local.ColorAtTarget; + this.clAtFromTarget = SettingManager.Local.ColorAtFromTarget; + this.clAtTo = SettingManager.Local.ColorAtTo; + this.clListBackcolor = SettingManager.Local.ColorListBackcolor; + this.clInputBackcolor = SettingManager.Local.ColorInputBackcolor; + this.clInputFont = SettingManager.Local.ColorInputFont; + this.fntInputFont = SettingManager.Local.FontInputFont; + this.brsBackColorMine.Dispose(); + this.brsBackColorAt.Dispose(); + this.brsBackColorYou.Dispose(); + this.brsBackColorAtYou.Dispose(); + this.brsBackColorAtFromTarget.Dispose(); + this.brsBackColorAtTo.Dispose(); + this.brsBackColorNone.Dispose(); + this.brsBackColorMine = new SolidBrush(this.clSelf); + this.brsBackColorAt = new SolidBrush(this.clAtSelf); + this.brsBackColorYou = new SolidBrush(this.clTarget); + this.brsBackColorAtYou = new SolidBrush(this.clAtTarget); + this.brsBackColorAtFromTarget = new SolidBrush(this.clAtFromTarget); + this.brsBackColorAtTo = new SolidBrush(this.clAtTo); + this.brsBackColorNone = new SolidBrush(this.clListBackcolor); try { - if (this.StatusText.Focused) this.StatusText.BackColor = this._clInputBackcolor; - this.StatusText.Font = this._fntInputFont; - this.StatusText.ForeColor = this._clInputFont; + if (this.StatusText.Focused) this.StatusText.BackColor = this.clInputBackcolor; + this.StatusText.Font = this.fntInputFont; + this.StatusText.ForeColor = this.clInputFont; } catch (Exception ex) { @@ -3637,7 +3637,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) { if (SettingManager.Common.TabIconDisp) { - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var tabPage = this.ListTab.TabPages[index]; if (tab.UnreadCount == 0) @@ -3656,7 +3656,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) try { - var oldIconCol = this._iconCol; + var oldIconCol = this.iconCol; if (SettingManager.Common.IconSize != oldIconSz) this.ApplyListViewIconSize(SettingManager.Common.IconSize); @@ -3668,10 +3668,10 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) using (ControlTransaction.Update(lst)) { lst.GridLines = SettingManager.Common.ShowGrid; - lst.Font = this._fntReaded; - lst.BackColor = this._clListBackcolor; + lst.Font = this.fntReaded; + lst.BackColor = this.clListBackcolor; - if (this._iconCol != oldIconCol) + if (this.iconCol != oldIconCol) this.ResetColumns(lst); } } @@ -3690,7 +3690,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) this.CurrentListView.Refresh(); this.ListTab.Refresh(); - this._hookGlobalHotkey.UnregisterAllOriginalHotkey(); + this.hookGlobalHotkey.UnregisterAllOriginalHotkey(); if (SettingManager.Common.HotkeyEnabled) { // グローバルホットキーの登録。設定で変更可能にするかも @@ -3704,7 +3704,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) if ((SettingManager.Common.HotkeyModifier & Keys.LWin) == Keys.LWin) modKey |= HookGlobalHotkey.ModKeys.Win; - this._hookGlobalHotkey.RegisterOriginalHotkey(SettingManager.Common.HotkeyKey, SettingManager.Common.HotkeyValue, modKey); + this.hookGlobalHotkey.RegisterOriginalHotkey(SettingManager.Common.HotkeyKey, SettingManager.Common.HotkeyValue, modKey); } if (SettingManager.Common.IsUseNotifyGrowl) this.gh.RegisterGrowl(); @@ -3745,7 +3745,7 @@ private void SetTabAlignment() this.ListTab.Alignment = newAlignment; - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var lst = (DetailsListView)this.ListTab.TabPages[index].Tag; using (ControlTransaction.Update(lst)) @@ -3759,7 +3759,7 @@ private void SetTabAlignment() private void ApplyListViewIconSize(MyCommon.IconSizes iconSz) { // アイコンサイズの再設定 - this._iconSz = iconSz switch + this.iconSz = iconSz switch { MyCommon.IconSizes.IconNone => 0, MyCommon.IconSizes.Icon16 => 16, @@ -3768,18 +3768,18 @@ private void ApplyListViewIconSize(MyCommon.IconSizes iconSz) MyCommon.IconSizes.Icon48_2 => 48, _ => throw new InvalidEnumArgumentException(nameof(iconSz), (int)iconSz, typeof(MyCommon.IconSizes)), }; - this._iconCol = iconSz == MyCommon.IconSizes.Icon48_2; + this.iconCol = iconSz == MyCommon.IconSizes.Icon48_2; - if (this._iconSz > 0) + if (this.iconSz > 0) { // ディスプレイの DPI 設定を考慮したサイズを設定する - this._listViewImageList.ImageSize = new Size( + this.listViewImageList.ImageSize = new Size( 1, - (int)Math.Ceiling(this._iconSz * this.CurrentScaleFactor.Height)); + (int)Math.Ceiling(this.iconSz * this.CurrentScaleFactor.Height)); } else { - this._listViewImageList.ImageSize = new Size(1, 1); + this.listViewImageList.ImageSize = new Size(1, 1); } } @@ -3811,11 +3811,11 @@ private void ResetColumns(DetailsListView list) public void AddNewTabForSearch(string searchWord) { // 同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了 - foreach (var tb in this._statuses.GetTabsByType()) + foreach (var tb in this.statuses.GetTabsByType()) { if (tb.SearchWords == searchWord && MyCommon.IsNullOrEmpty(tb.SearchLang)) { - var tabIndex = this._statuses.Tabs.IndexOf(tb); + var tabIndex = this.statuses.Tabs.IndexOf(tb); this.ListTab.SelectedIndex = tabIndex; return; } @@ -3824,17 +3824,17 @@ public void AddNewTabForSearch(string searchWord) var tabName = searchWord; for (var i = 0; i <= 100; i++) { - if (this._statuses.ContainsTab(tabName)) + if (this.statuses.ContainsTab(tabName)) tabName += "_"; else break; } // タブ追加 var tab = new PublicSearchTabModel(tabName); - this._statuses.AddTab(tab); + this.statuses.AddTab(tab); this.AddNewTab(tab, startup: false); // 追加したタブをアクティブに - this.ListTab.SelectedIndex = this._statuses.Tabs.Count - 1; + this.ListTab.SelectedIndex = this.statuses.Tabs.Count - 1; // 検索条件の設定 var tabPage = this.CurrentTabPage; var cmb = (ComboBox)tabPage.Controls["panelSearch"].Controls["comboSearch"]; @@ -3874,27 +3874,27 @@ private void SearchComboBox_KeyDown(object sender, KeyEventArgs e) public async Task AddNewTabForUserTimeline(string user) { // 同一検索条件のタブが既に存在すれば、そのタブアクティブにして終了 - foreach (var tb in this._statuses.GetTabsByType()) + foreach (var tb in this.statuses.GetTabsByType()) { if (tb.ScreenName == user) { - var tabIndex = this._statuses.Tabs.IndexOf(tb); + var tabIndex = this.statuses.Tabs.IndexOf(tb); this.ListTab.SelectedIndex = tabIndex; return; } } // ユニークなタブ名生成 var tabName = "user:" + user; - while (this._statuses.ContainsTab(tabName)) + while (this.statuses.ContainsTab(tabName)) { tabName += "_"; } // タブ追加 var tab = new UserTimelineTabModel(tabName, user); - this._statuses.AddTab(tab); + this.statuses.AddTab(tab); this.AddNewTab(tab, startup: false); // 追加したタブをアクティブに - this.ListTab.SelectedIndex = this._statuses.Tabs.Count - 1; + this.ListTab.SelectedIndex = this.statuses.Tabs.Count - 1; this.SaveConfigsTabs(); // 検索実行 await this.RefreshTabAsync(tab); @@ -3909,22 +3909,22 @@ public bool AddNewTab(TabModel tab, bool startup) // 新規タブ名チェック if (tab.TabName == Properties.Resources.AddNewTabText1) return false; - var _tabPage = new TabPage(); - var _listCustom = new DetailsListView(); + var tabPage = new TabPage(); + var listCustom = new DetailsListView(); - var cnt = this._statuses.Tabs.Count; + var cnt = this.statuses.Tabs.Count; // ToDo:Create and set controls follow tabtypes - using (ControlTransaction.Update(_listCustom)) + using (ControlTransaction.Update(listCustom)) using (ControlTransaction.Layout(this.SplitContainer1.Panel1, false)) using (ControlTransaction.Layout(this.SplitContainer1.Panel2, false)) using (ControlTransaction.Layout(this.SplitContainer1, false)) using (ControlTransaction.Layout(this.ListTab, false)) using (ControlTransaction.Layout(this)) - using (ControlTransaction.Layout(_tabPage, false)) + using (ControlTransaction.Layout(tabPage, false)) { - _tabPage.Controls.Add(_listCustom); + tabPage.Controls.Add(listCustom); // UserTimeline関連 var userTab = tab as UserTimelineTabModel; @@ -3953,7 +3953,7 @@ public bool AddNewTab(TabModel tab, bool startup) { label.Height = tmpComboBox.Height; } - _tabPage.Controls.Add(label); + tabPage.Controls.Add(label); } // 検索関連の準備 else if (searchTab != null) @@ -4042,71 +4042,71 @@ public bool AddNewTab(TabModel tab, bool startup) cmbLang.Text = searchTab.SearchLang; - _tabPage.Controls.Add(pnl); - } - } - - _tabPage.Tag = _listCustom; - this.ListTab.Controls.Add(_tabPage); - - _tabPage.Location = new Point(4, 4); - _tabPage.Name = "CTab" + cnt; - _tabPage.Size = new Size(380, 260); - _tabPage.TabIndex = 2 + cnt; - _tabPage.Text = tab.TabName; - _tabPage.UseVisualStyleBackColor = true; - _tabPage.AccessibleRole = AccessibleRole.PageTab; - - _listCustom.AccessibleName = Properties.Resources.AddNewTab_ListView_AccessibleName; - _listCustom.TabIndex = 1; - _listCustom.AllowColumnReorder = true; - _listCustom.ContextMenuStrip = this.ContextMenuOperate; - _listCustom.ColumnHeaderContextMenuStrip = this.ContextMenuColumnHeader; - _listCustom.Dock = DockStyle.Fill; - _listCustom.FullRowSelect = true; - _listCustom.HideSelection = false; - _listCustom.Location = new Point(0, 0); - _listCustom.Margin = new Padding(0); - _listCustom.Name = "CList" + Environment.TickCount; - _listCustom.ShowItemToolTips = true; - _listCustom.Size = new Size(380, 260); - _listCustom.UseCompatibleStateImageBehavior = false; - _listCustom.View = View.Details; - _listCustom.OwnerDraw = true; - _listCustom.VirtualMode = true; - _listCustom.Font = this._fntReaded; - _listCustom.BackColor = this._clListBackcolor; - - _listCustom.GridLines = SettingManager.Common.ShowGrid; - _listCustom.AllowDrop = true; - - _listCustom.SmallImageList = this._listViewImageList; - - this.InitColumns(_listCustom, startup); - - _listCustom.SelectedIndexChanged += this.MyList_SelectedIndexChanged; - _listCustom.MouseDoubleClick += this.MyList_MouseDoubleClick; - _listCustom.ColumnClick += this.MyList_ColumnClick; - _listCustom.DrawColumnHeader += this.MyList_DrawColumnHeader; - _listCustom.DragDrop += this.TweenMain_DragDrop; - _listCustom.DragEnter += this.TweenMain_DragEnter; - _listCustom.DragOver += this.TweenMain_DragOver; - _listCustom.DrawItem += this.MyList_DrawItem; - _listCustom.MouseClick += this.MyList_MouseClick; - _listCustom.ColumnReordered += this.MyList_ColumnReordered; - _listCustom.ColumnWidthChanged += this.MyList_ColumnWidthChanged; - _listCustom.CacheVirtualItems += this.MyList_CacheVirtualItems; - _listCustom.RetrieveVirtualItem += this.MyList_RetrieveVirtualItem; - _listCustom.DrawSubItem += this.MyList_DrawSubItem; - _listCustom.HScrolled += this.MyList_HScrolled; + tabPage.Controls.Add(pnl); + } + } + + tabPage.Tag = listCustom; + this.ListTab.Controls.Add(tabPage); + + tabPage.Location = new Point(4, 4); + tabPage.Name = "CTab" + cnt; + tabPage.Size = new Size(380, 260); + tabPage.TabIndex = 2 + cnt; + tabPage.Text = tab.TabName; + tabPage.UseVisualStyleBackColor = true; + tabPage.AccessibleRole = AccessibleRole.PageTab; + + listCustom.AccessibleName = Properties.Resources.AddNewTab_ListView_AccessibleName; + listCustom.TabIndex = 1; + listCustom.AllowColumnReorder = true; + listCustom.ContextMenuStrip = this.ContextMenuOperate; + listCustom.ColumnHeaderContextMenuStrip = this.ContextMenuColumnHeader; + listCustom.Dock = DockStyle.Fill; + listCustom.FullRowSelect = true; + listCustom.HideSelection = false; + listCustom.Location = new Point(0, 0); + listCustom.Margin = new Padding(0); + listCustom.Name = "CList" + Environment.TickCount; + listCustom.ShowItemToolTips = true; + listCustom.Size = new Size(380, 260); + listCustom.UseCompatibleStateImageBehavior = false; + listCustom.View = View.Details; + listCustom.OwnerDraw = true; + listCustom.VirtualMode = true; + listCustom.Font = this.fntReaded; + listCustom.BackColor = this.clListBackcolor; + + listCustom.GridLines = SettingManager.Common.ShowGrid; + listCustom.AllowDrop = true; + + listCustom.SmallImageList = this.listViewImageList; + + this.InitColumns(listCustom, startup); + + listCustom.SelectedIndexChanged += this.MyList_SelectedIndexChanged; + listCustom.MouseDoubleClick += this.MyList_MouseDoubleClick; + listCustom.ColumnClick += this.MyList_ColumnClick; + listCustom.DrawColumnHeader += this.MyList_DrawColumnHeader; + listCustom.DragDrop += this.TweenMain_DragDrop; + listCustom.DragEnter += this.TweenMain_DragEnter; + listCustom.DragOver += this.TweenMain_DragOver; + listCustom.DrawItem += this.MyList_DrawItem; + listCustom.MouseClick += this.MyList_MouseClick; + listCustom.ColumnReordered += this.MyList_ColumnReordered; + listCustom.ColumnWidthChanged += this.MyList_ColumnWidthChanged; + listCustom.CacheVirtualItems += this.MyList_CacheVirtualItems; + listCustom.RetrieveVirtualItem += this.MyList_RetrieveVirtualItem; + listCustom.DrawSubItem += this.MyList_DrawSubItem; + listCustom.HScrolled += this.MyList_HScrolled; } return true; } - public bool RemoveSpecifiedTab(string TabName, bool confirm) + public bool RemoveSpecifiedTab(string tabName, bool confirm) { - var tabInfo = this._statuses.GetTabByName(TabName); + var tabInfo = this.statuses.GetTabByName(tabName); if (tabInfo == null || tabInfo.IsDefaultTabType || tabInfo.Protected) return false; @@ -4115,7 +4115,7 @@ public bool RemoveSpecifiedTab(string TabName, bool confirm) var tmp = string.Format(Properties.Resources.RemoveSpecifiedTabText1, Environment.NewLine); var result = MessageBox.Show( tmp, - TabName + " " + Properties.Resources.RemoveSpecifiedTabText2, + tabName + " " + Properties.Resources.RemoveSpecifiedTabText2, MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); @@ -4125,45 +4125,45 @@ public bool RemoveSpecifiedTab(string TabName, bool confirm) } } - var tabIndex = this._statuses.Tabs.IndexOf(TabName); + var tabIndex = this.statuses.Tabs.IndexOf(tabName); if (tabIndex == -1) return false; - var _tabPage = this.ListTab.TabPages[tabIndex]; + var tabPage = this.ListTab.TabPages[tabIndex]; this.SetListProperty(); // 他のタブに列幅等を反映 // オブジェクトインスタンスの削除 - var _listCustom = (DetailsListView)_tabPage.Tag; - _tabPage.Tag = null; + var listCustom = (DetailsListView)tabPage.Tag; + tabPage.Tag = null; using (ControlTransaction.Layout(this.SplitContainer1.Panel1, false)) using (ControlTransaction.Layout(this.SplitContainer1.Panel2, false)) using (ControlTransaction.Layout(this.SplitContainer1, false)) using (ControlTransaction.Layout(this.ListTab, false)) using (ControlTransaction.Layout(this)) - using (ControlTransaction.Layout(_tabPage, false)) + using (ControlTransaction.Layout(tabPage, false)) { - if (this.CurrentTabName == TabName) + if (this.CurrentTabName == tabName) { - this.ListTab.SelectTab((this._beforeSelectedTab != null && this.ListTab.TabPages.Contains(this._beforeSelectedTab)) ? this._beforeSelectedTab : this.ListTab.TabPages[0]); - this._beforeSelectedTab = null; + this.ListTab.SelectTab((this.beforeSelectedTab != null && this.ListTab.TabPages.Contains(this.beforeSelectedTab)) ? this.beforeSelectedTab : this.ListTab.TabPages[0]); + this.beforeSelectedTab = null; } - this.ListTab.Controls.Remove(_tabPage); + this.ListTab.Controls.Remove(tabPage); // 後付けのコントロールを破棄 if (tabInfo.TabType == MyCommon.TabUsageType.UserTimeline || tabInfo.TabType == MyCommon.TabUsageType.Lists) { - using var label = _tabPage.Controls["labelUser"]; - _tabPage.Controls.Remove(label); + using var label = tabPage.Controls["labelUser"]; + tabPage.Controls.Remove(label); } else if (tabInfo.TabType == MyCommon.TabUsageType.PublicSearch) { - using var pnl = _tabPage.Controls["panelSearch"]; + using var pnl = tabPage.Controls["panelSearch"]; pnl.Enter -= this.SearchControls_Enter; pnl.Leave -= this.SearchControls_Leave; - _tabPage.Controls.Remove(pnl); + tabPage.Controls.Remove(pnl); foreach (Control ctrl in pnl.Controls) { @@ -4180,45 +4180,45 @@ public bool RemoveSpecifiedTab(string TabName, bool confirm) } } - _tabPage.Controls.Remove(_listCustom); + tabPage.Controls.Remove(listCustom); - _listCustom.SelectedIndexChanged -= this.MyList_SelectedIndexChanged; - _listCustom.MouseDoubleClick -= this.MyList_MouseDoubleClick; - _listCustom.ColumnClick -= this.MyList_ColumnClick; - _listCustom.DrawColumnHeader -= this.MyList_DrawColumnHeader; - _listCustom.DragDrop -= this.TweenMain_DragDrop; - _listCustom.DragEnter -= this.TweenMain_DragEnter; - _listCustom.DragOver -= this.TweenMain_DragOver; - _listCustom.DrawItem -= this.MyList_DrawItem; - _listCustom.MouseClick -= this.MyList_MouseClick; - _listCustom.ColumnReordered -= this.MyList_ColumnReordered; - _listCustom.ColumnWidthChanged -= this.MyList_ColumnWidthChanged; - _listCustom.CacheVirtualItems -= this.MyList_CacheVirtualItems; - _listCustom.RetrieveVirtualItem -= this.MyList_RetrieveVirtualItem; - _listCustom.DrawSubItem -= this.MyList_DrawSubItem; - _listCustom.HScrolled -= this.MyList_HScrolled; + listCustom.SelectedIndexChanged -= this.MyList_SelectedIndexChanged; + listCustom.MouseDoubleClick -= this.MyList_MouseDoubleClick; + listCustom.ColumnClick -= this.MyList_ColumnClick; + listCustom.DrawColumnHeader -= this.MyList_DrawColumnHeader; + listCustom.DragDrop -= this.TweenMain_DragDrop; + listCustom.DragEnter -= this.TweenMain_DragEnter; + listCustom.DragOver -= this.TweenMain_DragOver; + listCustom.DrawItem -= this.MyList_DrawItem; + listCustom.MouseClick -= this.MyList_MouseClick; + listCustom.ColumnReordered -= this.MyList_ColumnReordered; + listCustom.ColumnWidthChanged -= this.MyList_ColumnWidthChanged; + listCustom.CacheVirtualItems -= this.MyList_CacheVirtualItems; + listCustom.RetrieveVirtualItem -= this.MyList_RetrieveVirtualItem; + listCustom.DrawSubItem -= this.MyList_DrawSubItem; + listCustom.HScrolled -= this.MyList_HScrolled; - var cols = _listCustom.Columns.Cast().ToList(); - _listCustom.Columns.Clear(); + var cols = listCustom.Columns.Cast().ToList(); + listCustom.Columns.Clear(); cols.ForEach(col => col.Dispose()); cols.Clear(); - _listCustom.ContextMenuStrip = null; - _listCustom.ColumnHeaderContextMenuStrip = null; - _listCustom.Font = null; + listCustom.ContextMenuStrip = null; + listCustom.ColumnHeaderContextMenuStrip = null; + listCustom.Font = null; - _listCustom.SmallImageList = null; - _listCustom.ListViewItemSorter = null; + listCustom.SmallImageList = null; + listCustom.ListViewItemSorter = null; // キャッシュのクリア this.PurgeListViewItemCache(); } - _tabPage.Dispose(); - _listCustom.Dispose(); - this._statuses.RemoveTab(TabName); + tabPage.Dispose(); + listCustom.Dispose(); + this.statuses.RemoveTab(tabName); - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var lst = (DetailsListView)this.ListTab.TabPages[index].Tag; lst.VirtualListSize = tab.AllCount; @@ -4230,17 +4230,17 @@ public bool RemoveSpecifiedTab(string TabName, bool confirm) private void ListTab_Deselected(object sender, TabControlEventArgs e) { this.PurgeListViewItemCache(); - this._beforeSelectedTab = e.TabPage; + this.beforeSelectedTab = e.TabPage; } private void ListTab_MouseMove(object sender, MouseEventArgs e) { // タブのD&D - if (!SettingManager.Common.TabMouseLock && e.Button == MouseButtons.Left && this._tabDrag) + if (!SettingManager.Common.TabMouseLock && e.Button == MouseButtons.Left && this.tabDrag) { var tn = ""; - var dragEnableRectangle = new Rectangle(this._tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2), this._tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height); + var dragEnableRectangle = new Rectangle(this.tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2), this.tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height); if (!dragEnableRectangle.Contains(e.Location)) { // タブが多段の場合にはMouseDownの前の段階で選択されたタブの段が変わっているので、このタイミングでカーソルの位置からタブを判定出来ない。 @@ -4249,7 +4249,7 @@ private void ListTab_MouseMove(object sender, MouseEventArgs e) if (MyCommon.IsNullOrEmpty(tn)) return; - var tabIndex = this._statuses.Tabs.IndexOf(tn); + var tabIndex = this.statuses.Tabs.IndexOf(tn); if (tabIndex != -1) { var tabPage = this.ListTab.TabPages[tabIndex]; @@ -4258,16 +4258,16 @@ private void ListTab_MouseMove(object sender, MouseEventArgs e) } else { - this._tabDrag = false; + this.tabDrag = false; } var cpos = new Point(e.X, e.Y); - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var rect = this.ListTab.GetTabRect(index); if (rect.Contains(cpos)) { - this._rclickTabName = tab.TabName; + this.rclickTabName = tab.TabName; break; } } @@ -4287,7 +4287,7 @@ private void ListTab_SelectedIndexChanged(object sender, EventArgs e) private void SetListProperty() { - if (!this._isColumnChanged) return; + if (!this.isColumnChanged) return; var currentListView = this.CurrentListView; @@ -4321,7 +4321,7 @@ private void SetListProperty() } } - this._isColumnChanged = false; + this.isColumnChanged = false; } private void StatusText_KeyPress(object sender, KeyPressEventArgs e) @@ -4442,7 +4442,7 @@ private void StatusText_TextChanged(object sender, EventArgs e) } else { - this.StatusText.ForeColor = this._clInputFont; + this.StatusText.ForeColor = this.clInputFont; } this.StatusText.AccessibleDescription = string.Format(Properties.Resources.StatusText_AccessibleDescription, pLen); @@ -4484,28 +4484,28 @@ internal static bool TextContainsOnlyMentions(string text) /// private string RemoveAutoPopuratedMentions(string statusText, out long[] autoPopulatedUserIds) { - var _autoPopulatedUserIds = new List(); + var autoPopulatedUserIdList = new List(); - var replyToPost = this.inReplyTo != null ? this._statuses[this.inReplyTo.Value.StatusId] : null; + var replyToPost = this.inReplyTo != null ? this.statuses[this.inReplyTo.Value.StatusId] : null; if (replyToPost != null) { if (statusText.StartsWith($"@{replyToPost.ScreenName} ", StringComparison.Ordinal)) { statusText = statusText.Substring(replyToPost.ScreenName.Length + 2); - _autoPopulatedUserIds.Add(replyToPost.UserId); + autoPopulatedUserIdList.Add(replyToPost.UserId); foreach (var (userId, screenName) in replyToPost.ReplyToList) { if (statusText.StartsWith($"@{screenName} ", StringComparison.Ordinal)) { statusText = statusText.Substring(screenName.Length + 2); - _autoPopulatedUserIds.Add(userId); + autoPopulatedUserIdList.Add(userId); } } } } - autoPopulatedUserIds = _autoPopulatedUserIds.ToArray(); + autoPopulatedUserIds = autoPopulatedUserIdList.ToArray(); return statusText; } @@ -4668,7 +4668,7 @@ private void MyList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs if (sender != this.CurrentListView) return; - var listCache = this._listItemCache; + var listCache = this.listItemCache; if (listCache?.TargetList == sender && listCache.IsSupersetOf(e.StartIndex, e.EndIndex)) { // If the newly requested cache is a subset of the old cache, @@ -4682,7 +4682,7 @@ private void MyList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs private void MyList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) { - var listCache = this._listItemCache; + var listCache = this.listItemCache; if (listCache?.TargetList == sender) { if (listCache.TryGetValue(e.ItemIndex, out var item, out _)) @@ -4694,7 +4694,7 @@ private void MyList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventA // A cache miss, so create a new ListViewItem and pass it back. var tabPage = (TabPage)((DetailsListView)sender).Parent; - var tab = this._statuses.Tabs[tabPage.Text]; + var tab = this.statuses.Tabs[tabPage.Text]; try { e.Item = this.CreateItem(tab, tab[e.ItemIndex]); @@ -4738,57 +4738,57 @@ int FilterRange(int index) Cache = Enumerable.Zip(listItems, posts, (x, y) => (x, y)).ToArray(), }; - Interlocked.Exchange(ref this._listItemCache, listCache); + Interlocked.Exchange(ref this.listItemCache, listCache); } /// /// DetailsListView のための ListViewItem のキャッシュを消去する /// private void PurgeListViewItemCache() - => Interlocked.Exchange(ref this._listItemCache, null); + => Interlocked.Exchange(ref this.listItemCache, null); - private ListViewItem CreateItem(TabModel tab, PostClass Post) + private ListViewItem CreateItem(TabModel tab, PostClass post) { var mk = new StringBuilder(); - if (Post.FavoritedCount > 0) mk.Append("+" + Post.FavoritedCount); + if (post.FavoritedCount > 0) mk.Append("+" + post.FavoritedCount); ImageListViewItem itm; - if (Post.RetweetedId == null) + if (post.RetweetedId == null) { string[] sitem = { "", - Post.Nickname, - Post.IsDeleted ? "(DELETED)" : Post.AccessibleText.Replace('\n', ' '), - Post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), - Post.ScreenName, + post.Nickname, + post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), + post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), + post.ScreenName, "", mk.ToString(), - Post.Source }; - itm = new ImageListViewItem(sitem, this.IconCache, Post.ImageUrl); + post.Source }; + itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl); } else { string[] sitem = { "", - Post.Nickname, - Post.IsDeleted ? "(DELETED)" : Post.AccessibleText.Replace('\n', ' '), - Post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), - Post.ScreenName + Environment.NewLine + "(RT:" + Post.RetweetedBy + ")", + post.Nickname, + post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), + post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), + post.ScreenName + Environment.NewLine + "(RT:" + post.RetweetedBy + ")", "", mk.ToString(), - Post.Source }; - itm = new ImageListViewItem(sitem, this.IconCache, Post.ImageUrl); + post.Source }; + itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl); } - itm.StateIndex = Post.StateIndex; - itm.Tag = Post; + itm.StateIndex = post.StateIndex; + itm.Tag = post; - var read = Post.IsRead; + var read = post.IsRead; // 未読管理していなかったら既読として扱う if (!tab.UnreadManage || !SettingManager.Common.UnreadManage) read = true; - this.ChangeItemStyleRead(read, itm, Post, null); + this.ChangeItemStyleRead(read, itm, post, null); if (tab.TabName == this.CurrentTabName) - this.ColorizeList(itm, Post); + this.ColorizeList(itm, post); return itm; } @@ -4801,9 +4801,9 @@ private void ApplyPostFilters() using (ControlTransaction.Cursor(this, Cursors.WaitCursor)) { this.PurgeListViewItemCache(); - this._statuses.FilterAll(); + this.statuses.FilterAll(); - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var tabPage = this.ListTab.TabPages[index]; var listview = (DetailsListView)tabPage.Tag; @@ -4843,28 +4843,28 @@ private void MyList_DrawItem(object sender, DrawListViewItemEventArgs e) SolidBrush brs2; if (!e.Item.Selected) // e.ItemStateでうまく判定できない??? { - if (e.Item.BackColor == this._clSelf) - brs2 = this._brsBackColorMine; - else if (e.Item.BackColor == this._clAtSelf) - brs2 = this._brsBackColorAt; - else if (e.Item.BackColor == this._clTarget) - brs2 = this._brsBackColorYou; - else if (e.Item.BackColor == this._clAtTarget) - brs2 = this._brsBackColorAtYou; - else if (e.Item.BackColor == this._clAtFromTarget) - brs2 = this._brsBackColorAtFromTarget; - else if (e.Item.BackColor == this._clAtTo) - brs2 = this._brsBackColorAtTo; + if (e.Item.BackColor == this.clSelf) + brs2 = this.brsBackColorMine; + else if (e.Item.BackColor == this.clAtSelf) + brs2 = this.brsBackColorAt; + else if (e.Item.BackColor == this.clTarget) + brs2 = this.brsBackColorYou; + else if (e.Item.BackColor == this.clAtTarget) + brs2 = this.brsBackColorAtYou; + else if (e.Item.BackColor == this.clAtFromTarget) + brs2 = this.brsBackColorAtFromTarget; + else if (e.Item.BackColor == this.clAtTo) + brs2 = this.brsBackColorAtTo; else - brs2 = this._brsBackColorNone; + brs2 = this.brsBackColorNone; } else { // 選択中の行 if (((Control)sender).Focused) - brs2 = this._brsHighLight; + brs2 = this.brsHighLight; else - brs2 = this._brsDeactiveSelection; + brs2 = this.brsDeactiveSelection; } e.Graphics.FillRectangle(brs2, e.Bounds); e.DrawFocusRectangle(); @@ -4883,7 +4883,7 @@ private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) RectangleF rct = e.Bounds; rct.Width = e.Header.Width; var fontHeight = e.Item.Font.Height; - if (this._iconCol) + if (this.iconCol) { rct.Y += fontHeight; rct.Height -= fontHeight; @@ -4892,7 +4892,7 @@ private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) var drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, fontHeight, out var heightDiff)); // フォントの高さの半分を足してるのは保険。無くてもいいかも。 - if (this._iconCol || drawLineCount > 1) + if (this.iconCol || drawLineCount > 1) { if (heightDiff < fontHeight * 0.7) { @@ -4908,10 +4908,10 @@ private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) if (rct.Width > 0) { var color = (!e.Item.Selected) ? e.Item.ForeColor : // 選択されていない行 - ((Control)sender).Focused ? this._clHighLight : // 選択中の行 - this._clUnread; + ((Control)sender).Focused ? this.clHighLight : // 選択中の行 + this.clUnread; - if (this._iconCol) + if (this.iconCol) { var rctB = e.Bounds; rctB.Width = e.Header.Width; @@ -4990,7 +4990,7 @@ private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) private void DrawListViewItemIcon(DrawListViewItemEventArgs e) { - if (this._iconSz == 0) return; + if (this.iconSz == 0) return; var item = (ImageListViewItem)e.Item; @@ -5009,7 +5009,7 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) } // ディスプレイの DPI 設定を考慮したアイコンサイズ - var realIconSize = new SizeF(this._iconSz * this.CurrentScaleFactor.Width, this._iconSz * this.CurrentScaleFactor.Height).ToSize(); + var realIconSize = new SizeF(this.iconSz * this.CurrentScaleFactor.Width, this.iconSz * this.CurrentScaleFactor.Height).ToSize(); var realStateSize = new SizeF(16 * this.CurrentScaleFactor.Width, 16 * this.CurrentScaleFactor.Height).ToSize(); Rectangle iconRect; @@ -5185,7 +5185,7 @@ private void ShowSearchDialog() try { - tabName = this._statuses.MakeTabName(tabName); + tabName = this.statuses.MakeTabName(tabName); } catch (TabException ex) { @@ -5194,7 +5194,7 @@ private void ShowSearchDialog() var resultTab = new LocalSearchTabModel(tabName); this.AddNewTab(resultTab, startup: false); - this._statuses.AddTab(resultTab); + this.statuses.AddTab(resultTab); var targetTab = this.CurrentTab; @@ -5222,10 +5222,10 @@ private void ShowSearchDialog() resultTab.AddPostQueue(post); } - this._statuses.DistributePosts(); + this.statuses.DistributePosts(); this.RefreshTimeline(); - var tabIndex = this._statuses.Tabs.IndexOf(tabName); + var tabIndex = this.statuses.Tabs.IndexOf(tabName); this.ListTab.SelectedIndex = tabIndex; } else @@ -5275,7 +5275,7 @@ private void AboutMenuItem_Click(object sender, EventArgs e) private void JumpUnreadMenuItem_Click(object sender, EventArgs e) { - var bgnIdx = this._statuses.SelectedTabIndex; + var bgnIdx = this.statuses.SelectedTabIndex; if (this.ImageSelector.Enabled) return; @@ -5284,7 +5284,7 @@ private void JumpUnreadMenuItem_Click(object sender, EventArgs e) var foundIndex = 0; // 現在タブから最終タブまで探索 - foreach (var (tab, index) in this._statuses.Tabs.WithIndex().Skip(bgnIdx)) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex().Skip(bgnIdx)) { var unreadIndex = tab.NextUnreadIndex; if (unreadIndex != -1) @@ -5299,7 +5299,7 @@ private void JumpUnreadMenuItem_Click(object sender, EventArgs e) // 未読みつからず&現在タブが先頭ではなかったら、先頭タブから現在タブの手前まで探索 if (foundTab == null && bgnIdx > 0) { - foreach (var (tab, index) in this._statuses.Tabs.WithIndex().Take(bgnIdx)) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex().Take(bgnIdx)) { var unreadIndex = tab.NextUnreadIndex; if (unreadIndex != -1) @@ -5319,12 +5319,12 @@ private void JumpUnreadMenuItem_Click(object sender, EventArgs e) // 全部調べたが未読見つからず→先頭タブの最新発言へ this.ListTab.SelectedIndex = 0; var tabPage = this.ListTab.TabPages[0]; - var tab = this._statuses.Tabs[0]; + var tab = this.statuses.Tabs[0]; if (tab.AllCount == 0) return; - if (this._statuses.SortOrder == SortOrder.Ascending) + if (this.statuses.SortOrder == SortOrder.Ascending) foundIndex = tab.AllCount - 1; else foundIndex = 0; @@ -5333,16 +5333,16 @@ private void JumpUnreadMenuItem_Click(object sender, EventArgs e) } else { - var foundTabIndex = this._statuses.Tabs.IndexOf(foundTab); + var foundTabIndex = this.statuses.Tabs.IndexOf(foundTab); lst = (DetailsListView)this.ListTab.TabPages[foundTabIndex].Tag; } this.SelectListItem(lst, foundIndex); - if (this._statuses.SortMode == ComparerMode.Id) + if (this.statuses.SortMode == ComparerMode.Id) { - if (this._statuses.SortOrder == SortOrder.Ascending && lst.Items[foundIndex].Position.Y > lst.ClientSize.Height - this._iconSz - 10 || - this._statuses.SortOrder == SortOrder.Descending && lst.Items[foundIndex].Position.Y < this._iconSz + 10) + if (this.statuses.SortOrder == SortOrder.Ascending && lst.Items[foundIndex].Position.Y > lst.ClientSize.Height - this.iconSz - 10 || + this.statuses.SortOrder == SortOrder.Descending && lst.Items[foundIndex].Position.Y < this.iconSz + 10) { this.MoveTop(); } @@ -5504,7 +5504,7 @@ private void UpdateSelectedPost() if (SettingManager.Common.TabIconDisp) { - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { if (tab.UnreadCount == 0) { @@ -5597,7 +5597,7 @@ private async void ListTab_KeyDown(object sender, KeyEventArgs e) } if (e.Control || e.Shift || e.Alt) - this._anchorFlag = false; + this.anchorFlag = false; if (this.CommonKeyDown(e.KeyData, FocusedControl.ListTab, out var asyncTask)) { @@ -5651,7 +5651,7 @@ private void InitializeShortcuts() .NotFocusedOn(FocusedControl.StatusText) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; this.JumpUnreadMenuItem_Click(this.JumpUnreadMenuItem, EventArgs.Empty); }), @@ -5659,7 +5659,7 @@ private void InitializeShortcuts() .NotFocusedOn(FocusedControl.StatusText) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; this.ShowRelatedStatusesMenuItem_Click(this.ShowRelatedStatusesMenuItem, EventArgs.Empty); }), @@ -5692,7 +5692,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; this.GoPost(forward: true); }), @@ -5700,7 +5700,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; this.GoPost(forward: false); }), @@ -5708,7 +5708,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; this.MoveTop(); }), @@ -5716,7 +5716,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; this.GoNextTab(forward: true); }), @@ -5724,7 +5724,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; this.GoNextTab(forward: false); }), @@ -5733,7 +5733,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; return this.GoInReplyToPostTree(); }), @@ -5742,14 +5742,14 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; this.GoBackInReplyToPostTree(); }), ShortcutCommand.Create(Keys.Escape) .FocusedOn(FocusedControl.ListTab) .Do(() => { - this._anchorFlag = false; + this.anchorFlag = false; var tab = this.CurrentTab; var tabtype = tab.TabType; if (tabtype == MyCommon.TabUsageType.Related || tabtype == MyCommon.TabUsageType.UserTimeline || tabtype == MyCommon.TabUsageType.PublicSearch || tabtype == MyCommon.TabUsageType.SearchResults) @@ -5762,7 +5762,7 @@ private void InitializeShortcuts() // 上下キー, PageUp/Downキー, Home/Endキー は既定の動作を残しつつアンカー初期化 ShortcutCommand.Create(Keys.Up, Keys.Down, Keys.PageUp, Keys.PageDown, Keys.Home, Keys.End) .FocusedOn(FocusedControl.ListTab) - .Do(() => this._anchorFlag = false, preventDefault: false), + .Do(() => this.anchorFlag = false, preventDefault: false), // PreviewKeyDownEventArgs.IsInputKey を true にしてスクロールを発生させる ShortcutCommand.Create(Keys.Up, Keys.Down) @@ -5779,7 +5779,7 @@ private void InitializeShortcuts() .Do(() => this.MakeReplyOrDirectStatus(isAuto: false, isReply: false)), ShortcutCommand.Create(Keys.Control | Keys.S) - .Do(() => this.FavoriteChange(FavAdd: true)), + .Do(() => this.FavoriteChange(favAdd: true)), ShortcutCommand.Create(Keys.Control | Keys.I) .Do(() => this.DoRepliedStatusOpen()), @@ -5837,47 +5837,47 @@ private void InitializeShortcuts() // タブダイレクト選択(Ctrl+1~8,Ctrl+9) ShortcutCommand.Create(Keys.Control | Keys.D1) .FocusedOn(FocusedControl.ListTab) - .OnlyWhen(() => this._statuses.Tabs.Count >= 1) + .OnlyWhen(() => this.statuses.Tabs.Count >= 1) .Do(() => this.ListTab.SelectedIndex = 0), ShortcutCommand.Create(Keys.Control | Keys.D2) .FocusedOn(FocusedControl.ListTab) - .OnlyWhen(() => this._statuses.Tabs.Count >= 2) + .OnlyWhen(() => this.statuses.Tabs.Count >= 2) .Do(() => this.ListTab.SelectedIndex = 1), ShortcutCommand.Create(Keys.Control | Keys.D3) .FocusedOn(FocusedControl.ListTab) - .OnlyWhen(() => this._statuses.Tabs.Count >= 3) + .OnlyWhen(() => this.statuses.Tabs.Count >= 3) .Do(() => this.ListTab.SelectedIndex = 2), ShortcutCommand.Create(Keys.Control | Keys.D4) .FocusedOn(FocusedControl.ListTab) - .OnlyWhen(() => this._statuses.Tabs.Count >= 4) + .OnlyWhen(() => this.statuses.Tabs.Count >= 4) .Do(() => this.ListTab.SelectedIndex = 3), ShortcutCommand.Create(Keys.Control | Keys.D5) .FocusedOn(FocusedControl.ListTab) - .OnlyWhen(() => this._statuses.Tabs.Count >= 5) + .OnlyWhen(() => this.statuses.Tabs.Count >= 5) .Do(() => this.ListTab.SelectedIndex = 4), ShortcutCommand.Create(Keys.Control | Keys.D6) .FocusedOn(FocusedControl.ListTab) - .OnlyWhen(() => this._statuses.Tabs.Count >= 6) + .OnlyWhen(() => this.statuses.Tabs.Count >= 6) .Do(() => this.ListTab.SelectedIndex = 5), ShortcutCommand.Create(Keys.Control | Keys.D7) .FocusedOn(FocusedControl.ListTab) - .OnlyWhen(() => this._statuses.Tabs.Count >= 7) + .OnlyWhen(() => this.statuses.Tabs.Count >= 7) .Do(() => this.ListTab.SelectedIndex = 6), ShortcutCommand.Create(Keys.Control | Keys.D8) .FocusedOn(FocusedControl.ListTab) - .OnlyWhen(() => this._statuses.Tabs.Count >= 8) + .OnlyWhen(() => this.statuses.Tabs.Count >= 8) .Do(() => this.ListTab.SelectedIndex = 7), ShortcutCommand.Create(Keys.Control | Keys.D9) .FocusedOn(FocusedControl.ListTab) - .Do(() => this.ListTab.SelectedIndex = this._statuses.Tabs.Count - 1), + .Do(() => this.ListTab.SelectedIndex = this.statuses.Tabs.Count - 1), ShortcutCommand.Create(Keys.Control | Keys.A) .FocusedOn(FocusedControl.StatusText) @@ -5950,11 +5950,11 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Shift | Keys.H) .FocusedOn(FocusedControl.ListTab) - .Do(() => this.GoTopEnd(GoTop: true)), + .Do(() => this.GoTopEnd(goTop: true)), ShortcutCommand.Create(Keys.Shift | Keys.L) .FocusedOn(FocusedControl.ListTab) - .Do(() => this.GoTopEnd(GoTop: false)), + .Do(() => this.GoTopEnd(goTop: false)), ShortcutCommand.Create(Keys.Shift | Keys.M) .FocusedOn(FocusedControl.ListTab) @@ -5995,7 +5995,7 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Alt | Keys.P) .OnlyWhen(() => this.CurrentPost != null) - .Do(() => this.DoShowUserStatus(this.CurrentPost!.ScreenName, ShowInputDialog: false)), + .Do(() => this.DoShowUserStatus(this.CurrentPost!.ScreenName, showInputDialog: false)), ShortcutCommand.Create(Keys.Alt | Keys.Up) .Do(() => this.tweetDetailsView.ScrollDownPostBrowser(forward: false)), @@ -6029,7 +6029,7 @@ private void InitializeShortcuts() .Do(() => this.CurrentTabPage.Controls["panelSearch"].Controls["comboSearch"].Focus()), ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.S) - .Do(() => this.FavoriteChange(FavAdd: false)), + .Do(() => this.FavoriteChange(favAdd: false)), ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.B) .Do(() => this.UnreadStripMenuItem_Click(this.UnreadStripMenuItem, EventArgs.Empty)), @@ -6202,8 +6202,8 @@ internal bool CommonKeyDown(Keys keyData, FocusedControl focusedOn, out Task? as private void GoNextTab(bool forward) { - var idx = this._statuses.SelectedTabIndex; - var tabCount = this._statuses.Tabs.Count; + var idx = this.statuses.SelectedTabIndex; + var tabCount = this.statuses.Tabs.Count; if (forward) { idx += 1; @@ -6221,7 +6221,7 @@ private void CopyStot() { var sb = new StringBuilder(); var tab = this.CurrentTab; - var IsProtected = false; + var isProtected = false; var isDm = tab.TabType == MyCommon.TabUsageType.DirectMessage; foreach (var post in tab.SelectedPosts) { @@ -6238,7 +6238,7 @@ private void CopyStot() sb.AppendFormat("{0}:{1} [{2}]{3}", post.ScreenName, post.TextSingleLine, post.StatusId, Environment.NewLine); } } - if (IsProtected) + if (isProtected) { MessageBox.Show(Properties.Resources.CopyStotText1); } @@ -6379,7 +6379,7 @@ private void GoSamePostToAnotherTab(bool left) for (var tabidx = fIdx; tabidx != toIdx; tabidx += stp) { - var targetTab = this._statuses.Tabs[tabidx]; + var targetTab = this.statuses.Tabs[tabidx]; // Directタブは対象外 if (targetTab.TabType == MyCommon.TabUsageType.DirectMessage) @@ -6484,29 +6484,29 @@ private void GoRelPost(bool forward) stp = -1; } - if (!this._anchorFlag) + if (!this.anchorFlag) { var currentPost = this.CurrentPost; if (currentPost == null) return; - this._anchorPost = currentPost; - this._anchorFlag = true; + this.anchorPost = currentPost; + this.anchorFlag = true; } else { - if (this._anchorPost == null) return; + if (this.anchorPost == null) return; } for (var idx = fIdx; idx != toIdx; idx += stp) { var post = tab[idx]; - if (post.ScreenName == this._anchorPost.ScreenName || - post.RetweetedBy == this._anchorPost.ScreenName || - post.ScreenName == this._anchorPost.RetweetedBy || - (!MyCommon.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == this._anchorPost.RetweetedBy) || - this._anchorPost.ReplyToList.Any(x => x.UserId == post.UserId) || - this._anchorPost.ReplyToList.Any(x => x.UserId == post.RetweetedByUserId) || - post.ReplyToList.Any(x => x.UserId == this._anchorPost.UserId) || - post.ReplyToList.Any(x => x.UserId == this._anchorPost.RetweetedByUserId)) + if (post.ScreenName == this.anchorPost.ScreenName || + post.RetweetedBy == this.anchorPost.ScreenName || + post.ScreenName == this.anchorPost.RetweetedBy || + (!MyCommon.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == this.anchorPost.RetweetedBy) || + this.anchorPost.ReplyToList.Any(x => x.UserId == post.UserId) || + this.anchorPost.ReplyToList.Any(x => x.UserId == post.RetweetedByUserId) || + post.ReplyToList.Any(x => x.UserId == this.anchorPost.UserId) || + post.ReplyToList.Any(x => x.UserId == this.anchorPost.RetweetedByUserId)) { var listView = this.CurrentListView; this.SelectListItem(listView, idx); @@ -6518,8 +6518,8 @@ private void GoRelPost(bool forward) private void GoAnchor() { - if (this._anchorPost == null) return; - var idx = this.CurrentTab.IndexOf(this._anchorPost.StatusId); + if (this.anchorPost == null) return; + var idx = this.CurrentTab.IndexOf(this.anchorPost.StatusId); if (idx == -1) return; var listView = this.CurrentListView; @@ -6527,30 +6527,30 @@ private void GoAnchor() listView.EnsureVisible(idx); } - private void GoTopEnd(bool GoTop) + private void GoTopEnd(bool goTop) { var listView = this.CurrentListView; if (listView.VirtualListSize == 0) return; - ListViewItem _item; + ListViewItem item; int idx; - if (GoTop) + if (goTop) { - _item = listView.GetItemAt(0, 25); - if (_item == null) + item = listView.GetItemAt(0, 25); + if (item == null) idx = 0; else - idx = _item.Index; + idx = item.Index; } else { - _item = listView.GetItemAt(0, listView.ClientSize.Height - 1); - if (_item == null) + item = listView.GetItemAt(0, listView.ClientSize.Height - 1); + if (item == null) idx = listView.VirtualListSize - 1; else - idx = _item.Index; + idx = item.Index; } this.SelectListItem(listView, idx); } @@ -6561,29 +6561,29 @@ private void GoMiddle() if (listView.VirtualListSize == 0) return; - ListViewItem _item; + ListViewItem item; int idx1; int idx2; int idx3; - _item = listView.GetItemAt(0, 0); - if (_item == null) + item = listView.GetItemAt(0, 0); + if (item == null) { idx1 = 0; } else { - idx1 = _item.Index; + idx1 = item.Index; } - _item = listView.GetItemAt(0, listView.ClientSize.Height - 1); - if (_item == null) + item = listView.GetItemAt(0, listView.ClientSize.Height - 1); + if (item == null) { idx2 = listView.VirtualListSize - 1; } else { - idx2 = _item.Index; + idx2 = item.Index; } idx3 = (idx1 + idx2) / 2; @@ -6595,7 +6595,7 @@ private void GoLast() var listView = this.CurrentListView; if (listView.VirtualListSize == 0) return; - if (this._statuses.SortOrder == SortOrder.Ascending) + if (this.statuses.SortOrder == SortOrder.Ascending) { this.SelectListItem(listView, listView.VirtualListSize - 1); listView.EnsureVisible(listView.VirtualListSize - 1); @@ -6612,7 +6612,7 @@ private void MoveTop() var listView = this.CurrentListView; if (listView.SelectedIndices.Count == 0) return; var idx = listView.SelectedIndices[0]; - if (this._statuses.SortOrder == SortOrder.Ascending) + if (this.statuses.SortOrder == SortOrder.Ascending) { listView.EnsureVisible(listView.VirtualListSize - 1); } @@ -6664,7 +6664,7 @@ private async Task GoInReplyToPostTree() var inReplyToId = currentPost.InReplyToStatusId.Value; var inReplyToUser = currentPost.InReplyToUser; - var inReplyToPosts = from tab in this._statuses.Tabs + var inReplyToPosts = from tab in this.statuses.Tabs orderby tab != curTabClass from post in tab.Posts.Values where post.StatusId == inReplyToId @@ -6683,8 +6683,8 @@ await Task.Run(async () => .ConfigureAwait(false); post.IsRead = true; - this._statuses.AddPost(post); - this._statuses.DistributePosts(); + this.statuses.AddPost(post); + this.statuses.DistributePosts(); }); } catch (WebApiException ex) @@ -6706,7 +6706,7 @@ await Task.Run(async () => inReplyToTabName = inReplyPost.Tab.TabName; inReplyToIndex = inReplyPost.Index; - var tabIndex = this._statuses.Tabs.IndexOf(inReplyToTabName); + var tabIndex = this.statuses.Tabs.IndexOf(inReplyToTabName); var tabPage = this.ListTab.TabPages[tabIndex]; var listView = (DetailsListView)tabPage.Tag; @@ -6731,7 +6731,7 @@ private void GoBackInReplyToPostTree(bool parallel = false, bool isForward = tru { if (currentPost.InReplyToStatusId != null) { - var posts = from t in this._statuses.Tabs + var posts = from t in this.statuses.Tabs from p in t.Posts where p.Value.StatusId != currentPost.StatusId && p.Value.InReplyToStatusId == currentPost.InReplyToStatusId let indexOf = t.IndexOf(p.Value.StatusId) @@ -6754,7 +6754,7 @@ where indexOf > -1 var post = postList.FirstOrDefault(pst => pst.Tab == curTabClass && isForward ? pst.Index > currentIndex : pst.Index < currentIndex); if (post == null) post = postList.FirstOrDefault(pst => pst.Tab != curTabClass); if (post == null) post = postList.First(); - var tabIndex = this._statuses.Tabs.IndexOf(post.Tab); + var tabIndex = this.statuses.Tabs.IndexOf(post.Tab); this.ListTab.SelectedIndex = tabIndex; var listView = this.CurrentListView; this.SelectListItem(listView, post.Index); @@ -6770,7 +6770,7 @@ where indexOf > -1 { if (this.replyChains == null || this.replyChains.Count < 1) { - var posts = from t in this._statuses.Tabs + var posts = from t in this.statuses.Tabs from p in t.Posts where p.Value.InReplyToStatusId == currentPost.StatusId let indexOf = t.IndexOf(p.Value.StatusId) @@ -6781,7 +6781,7 @@ orderby indexOf try { var post = posts.First(); - var tabIndex = this._statuses.Tabs.IndexOf(post.Tab); + var tabIndex = this.statuses.Tabs.IndexOf(post.Tab); this.ListTab.SelectedIndex = tabIndex; var listView = this.CurrentListView; this.SelectListItem(listView, post.Index); @@ -6798,7 +6798,7 @@ orderby indexOf if (chainHead.InReplyToId == currentPost.StatusId) { var tab = chainHead.OriginalTab; - if (!this._statuses.Tabs.Contains(tab)) + if (!this.statuses.Tabs.Contains(tab)) { this.replyChains = null; } @@ -6811,7 +6811,7 @@ orderby indexOf } else { - var tabIndex = this._statuses.Tabs.IndexOf(tab); + var tabIndex = this.statuses.Tabs.IndexOf(tab); try { this.ListTab.SelectedIndex = tabIndex; @@ -6849,7 +6849,7 @@ private void GoBackSelectPostChain() this.selectPostChains.Pop(); var (tab, post) = this.selectPostChains.Peek(); - if (!this._statuses.Tabs.Contains(tab)) + if (!this.statuses.Tabs.Contains(tab)) continue; // 該当タブが存在しないので無視 if (post != null) @@ -6879,7 +6879,7 @@ private void GoBackSelectPostChain() return; } - var tabIndex = this._statuses.Tabs.IndexOf(foundTab); + var tabIndex = this.statuses.Tabs.IndexOf(foundTab); var tabPage = this.ListTab.TabPages[tabIndex]; var lst = (DetailsListView)tabPage.Tag; this.ListTab.SelectedIndex = tabIndex; @@ -6931,7 +6931,7 @@ private bool GoStatus(long statusId) { if (statusId == 0) return false; - var tab = this._statuses.Tabs + var tab = this.statuses.Tabs .Where(x => x.TabType != MyCommon.TabUsageType.DirectMessage) .Where(x => x.Contains(statusId)) .FirstOrDefault(); @@ -6941,7 +6941,7 @@ private bool GoStatus(long statusId) var index = tab.IndexOf(statusId); - var tabIndex = this._statuses.Tabs.IndexOf(tab); + var tabIndex = this.statuses.Tabs.IndexOf(tab); this.ListTab.SelectedIndex = tabIndex; var listView = this.CurrentListView; @@ -6955,13 +6955,13 @@ private bool GoDirectMessage(long statusId) { if (statusId == 0) return false; - var tab = this._statuses.DirectMessageTab; + var tab = this.statuses.DirectMessageTab; var index = tab.IndexOf(statusId); if (index == -1) return false; - var tabIndex = this._statuses.Tabs.IndexOf(tab); + var tabIndex = this.statuses.Tabs.IndexOf(tab); this.ListTab.SelectedIndex = tabIndex; var listView = this.CurrentListView; @@ -6972,19 +6972,19 @@ private bool GoDirectMessage(long statusId) } private void MyList_MouseClick(object sender, MouseEventArgs e) - => this._anchorFlag = false; + => this.anchorFlag = false; private void StatusText_Enter(object sender, EventArgs e) { // フォーカスの戻り先を StatusText に設定 this.Tag = this.StatusText; - this.StatusText.BackColor = this._clInputBackcolor; + this.StatusText.BackColor = this.clInputBackcolor; } public Color InputBackColor { - get => this._clInputBackcolor; - set => this._clInputBackcolor = value; + get => this.clInputBackcolor; + set => this.clInputBackcolor = value; } private void StatusText_Leave(object sender, EventArgs e) @@ -7027,7 +7027,7 @@ private void SaveConfigsAll(bool ifModified) private void SaveConfigsAtId() { - if (this._ignoreConfigSave || !SettingManager.Common.UseAtIdSupplement && this.AtIdSupl == null) return; + if (this.ignoreConfigSave || !SettingManager.Common.UseAtIdSupplement && this.AtIdSupl == null) return; this.ModifySettingAtId = false; SettingManager.AtIdList.AtIdList = this.AtIdSupl.GetItemList(); @@ -7036,24 +7036,24 @@ private void SaveConfigsAtId() private void SaveConfigsCommon() { - if (this._ignoreConfigSave) return; + if (this.ignoreConfigSave) return; this.ModifySettingCommon = false; - lock (this._syncObject) + lock (this.syncObject) { SettingManager.Common.UserName = this.tw.Username; SettingManager.Common.UserId = this.tw.UserId; SettingManager.Common.Token = this.tw.AccessToken; SettingManager.Common.TokenSecret = this.tw.AccessTokenSecret; - SettingManager.Common.SortOrder = (int)this._statuses.SortOrder; - SettingManager.Common.SortColumn = this._statuses.SortMode switch + SettingManager.Common.SortOrder = (int)this.statuses.SortOrder; + SettingManager.Common.SortColumn = this.statuses.SortMode switch { ComparerMode.Nickname => 1, // ニックネーム ComparerMode.Data => 2, // 本文 ComparerMode.Id => 3, // 時刻=発言Id ComparerMode.Name => 4, // 名前 ComparerMode.Source => 7, // Source - _ => throw new InvalidOperationException($"Invalid sort mode: {this._statuses.SortMode}"), + _ => throw new InvalidOperationException($"Invalid sort mode: {this.statuses.SortMode}"), }; SettingManager.Common.HashTags = this.HashMgr.HashHistories; if (this.HashMgr.IsPermanent) @@ -7076,41 +7076,41 @@ private void SaveConfigsCommon() private void SaveConfigsLocal() { - if (this._ignoreConfigSave) return; - lock (this._syncObject) + if (this.ignoreConfigSave) return; + lock (this.syncObject) { this.ModifySettingLocal = false; SettingManager.Local.ScaleDimension = this.CurrentAutoScaleDimensions; - SettingManager.Local.FormSize = this._mySize; - SettingManager.Local.FormLocation = this._myLoc; - SettingManager.Local.SplitterDistance = this._mySpDis; - SettingManager.Local.PreviewDistance = this._mySpDis3; + SettingManager.Local.FormSize = this.mySize; + SettingManager.Local.FormLocation = this.myLoc; + SettingManager.Local.SplitterDistance = this.mySpDis; + SettingManager.Local.PreviewDistance = this.mySpDis3; SettingManager.Local.StatusMultiline = this.StatusText.Multiline; - SettingManager.Local.StatusTextHeight = this._mySpDis2; - - SettingManager.Local.FontUnread = this._fntUnread; - SettingManager.Local.ColorUnread = this._clUnread; - SettingManager.Local.FontRead = this._fntReaded; - SettingManager.Local.ColorRead = this._clReaded; - SettingManager.Local.FontDetail = this._fntDetail; - SettingManager.Local.ColorDetail = this._clDetail; - SettingManager.Local.ColorDetailBackcolor = this._clDetailBackcolor; - SettingManager.Local.ColorDetailLink = this._clDetailLink; - SettingManager.Local.ColorFav = this._clFav; - SettingManager.Local.ColorOWL = this._clOWL; - SettingManager.Local.ColorRetweet = this._clRetweet; - SettingManager.Local.ColorSelf = this._clSelf; - SettingManager.Local.ColorAtSelf = this._clAtSelf; - SettingManager.Local.ColorTarget = this._clTarget; - SettingManager.Local.ColorAtTarget = this._clAtTarget; - SettingManager.Local.ColorAtFromTarget = this._clAtFromTarget; - SettingManager.Local.ColorAtTo = this._clAtTo; - SettingManager.Local.ColorListBackcolor = this._clListBackcolor; - SettingManager.Local.ColorInputBackcolor = this._clInputBackcolor; - SettingManager.Local.ColorInputFont = this._clInputFont; - SettingManager.Local.FontInputFont = this._fntInputFont; - - if (this._ignoreConfigSave) return; + SettingManager.Local.StatusTextHeight = this.mySpDis2; + + SettingManager.Local.FontUnread = this.fntUnread; + SettingManager.Local.ColorUnread = this.clUnread; + SettingManager.Local.FontRead = this.fntReaded; + SettingManager.Local.ColorRead = this.clReaded; + SettingManager.Local.FontDetail = this.fntDetail; + SettingManager.Local.ColorDetail = this.clDetail; + SettingManager.Local.ColorDetailBackcolor = this.clDetailBackcolor; + SettingManager.Local.ColorDetailLink = this.clDetailLink; + SettingManager.Local.ColorFav = this.clFav; + SettingManager.Local.ColorOWL = this.clOWL; + SettingManager.Local.ColorRetweet = this.clRetweet; + SettingManager.Local.ColorSelf = this.clSelf; + SettingManager.Local.ColorAtSelf = this.clAtSelf; + SettingManager.Local.ColorTarget = this.clTarget; + SettingManager.Local.ColorAtTarget = this.clAtTarget; + SettingManager.Local.ColorAtFromTarget = this.clAtFromTarget; + SettingManager.Local.ColorAtTo = this.clAtTo; + SettingManager.Local.ColorListBackcolor = this.clListBackcolor; + SettingManager.Local.ColorInputBackcolor = this.clInputBackcolor; + SettingManager.Local.ColorInputFont = this.clInputFont; + SettingManager.Local.FontInputFont = this.fntInputFont; + + if (this.ignoreConfigSave) return; SettingManager.SaveLocal(); } } @@ -7119,7 +7119,7 @@ private void SaveConfigsTabs() { var tabSettingList = new List(); - var tabs = this._statuses.Tabs.Append(this._statuses.MuteTab); + var tabs = this.statuses.Tabs.Append(this.statuses.MuteTab); foreach (var tab in tabs) { @@ -7266,25 +7266,25 @@ public bool TabRename(string origTabName, [NotNullWhen(true)] out string? newTab if (!MyCommon.IsNullOrEmpty(newTabName)) { // 新タブ名存在チェック - if (this._statuses.ContainsTab(newTabName)) + if (this.statuses.ContainsTab(newTabName)) { var tmp = string.Format(Properties.Resources.Tabs_DoubleClickText1, newTabName); MessageBox.Show(tmp, Properties.Resources.Tabs_DoubleClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); return false; } - var tabIndex = this._statuses.Tabs.IndexOf(origTabName); + var tabIndex = this.statuses.Tabs.IndexOf(origTabName); var tabPage = this.ListTab.TabPages[tabIndex]; // タブ名を変更 if (tabPage != null) tabPage.Text = newTabName; - this._statuses.RenameTab(origTabName, newTabName); + this.statuses.RenameTab(origTabName, newTabName); this.SaveConfigsCommon(); this.SaveConfigsTabs(); - this._rclickTabName = newTabName; + this.rclickTabName = newTabName; return true; } else @@ -7297,7 +7297,7 @@ private void ListTab_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Middle) { - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { if (this.ListTab.GetTabRect(index).Contains(e.Location)) { @@ -7317,19 +7317,19 @@ private void ListTab_MouseDown(object sender, MouseEventArgs e) if (SettingManager.Common.TabMouseLock) return; if (e.Button == MouseButtons.Left) { - foreach (var i in Enumerable.Range(0, this._statuses.Tabs.Count)) + foreach (var i in Enumerable.Range(0, this.statuses.Tabs.Count)) { if (this.ListTab.GetTabRect(i).Contains(e.Location)) { - this._tabDrag = true; - this._tabMouseDownPoint = e.Location; + this.tabDrag = true; + this.tabMouseDownPoint = e.Location; break; } } } else { - this._tabDrag = false; + this.tabDrag = false; } } @@ -7345,12 +7345,12 @@ private void ListTab_DragDrop(object sender, DragEventArgs e) { if (!e.Data.GetDataPresent(typeof(TabPage))) return; - this._tabDrag = false; + this.tabDrag = false; var tn = ""; var bef = false; var cpos = new Point(e.X, e.Y); var spos = this.ListTab.PointToClient(cpos); - foreach (var (tab, index) in this._statuses.Tabs.WithIndex()) + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var rect = this.ListTab.GetTabRect(index); if (rect.Contains(spos)) @@ -7368,7 +7368,7 @@ private void ListTab_DragDrop(object sender, DragEventArgs e) // タブのないところにドロップ->最後尾へ移動 if (MyCommon.IsNullOrEmpty(tn)) { - var lastTab = this._statuses.Tabs.Last(); + var lastTab = this.statuses.Tabs.Last(); tn = lastTab.TabName; bef = false; } @@ -7391,7 +7391,7 @@ public void ReOrderTab(string targetTabText, string baseTabText, bool isBeforeBa using (ControlTransaction.Layout(this.ListTab)) { - var tab = this._statuses.Tabs[targetIndex]; + var tab = this.statuses.Tabs[targetIndex]; var tabPage = this.ListTab.TabPages[targetIndex]; this.ListTab.TabPages.Remove(tabPage); @@ -7402,7 +7402,7 @@ public void ReOrderTab(string targetTabText, string baseTabText, bool isBeforeBa if (!isBeforeBaseTab) baseIndex++; - this._statuses.MoveTab(baseIndex, tab); + this.statuses.MoveTab(baseIndex, tab); this.ListTab.TabPages.Insert(baseIndex, tabPage); } @@ -7657,7 +7657,7 @@ private void MakeReplyOrDirectStatus(bool isAuto = true, bool isReply = true, bo } private void ListTab_MouseUp(object sender, MouseEventArgs e) - => this._tabDrag = false; + => this.tabDrag = false; private int iconCnt = 0; private int blinkCnt = 0; @@ -7675,11 +7675,11 @@ void DisableTasktrayAnimation() if (busyTasks) { this.iconCnt += 1; - if (this.iconCnt >= this.NIconRefresh.Length) + if (this.iconCnt >= this.nIconRefresh.Length) this.iconCnt = 0; - this.NotifyIcon1.Icon = this.NIconRefresh[this.iconCnt]; - this._myStatusError = false; + this.NotifyIcon1.Icon = this.nIconRefresh[this.iconCnt]; + this.myStatusError = false; EnableTasktrayAnimation(); return; } @@ -7688,7 +7688,7 @@ void DisableTasktrayAnimation() var reply = false; if (replyIconType != MyCommon.REPLY_ICONSTATE.None) { - var replyTab = this._statuses.GetTabByType(); + var replyTab = this.statuses.GetTabByType(); if (replyTab != null && replyTab.UnreadCount > 0) reply = true; } @@ -7702,7 +7702,7 @@ void DisableTasktrayAnimation() if (this.blinkCnt == 0) this.blink = !this.blink; - this.NotifyIcon1.Icon = this.blink ? this.ReplyIconBlink : this.ReplyIcon; + this.NotifyIcon1.Icon = this.blink ? this.replyIconBlink : this.replyIcon; EnableTasktrayAnimation(); return; } @@ -7716,13 +7716,13 @@ void DisableTasktrayAnimation() // 優先度:リプライ→エラー→オフライン→アイドル // エラーは更新アイコンでクリアされる if (replyIconType == MyCommon.REPLY_ICONSTATE.StaticIcon && reply) - this.NotifyIcon1.Icon = this.ReplyIcon; - else if (this._myStatusError) - this.NotifyIcon1.Icon = this.NIconAtRed; - else if (this._myStatusOnline) - this.NotifyIcon1.Icon = this.NIconAt; + this.NotifyIcon1.Icon = this.replyIcon; + else if (this.myStatusError) + this.NotifyIcon1.Icon = this.nIconAtRed; + else if (this.myStatusOnline) + this.NotifyIcon1.Icon = this.nIconAt; else - this.NotifyIcon1.Icon = this.NIconAtSmoke; + this.NotifyIcon1.Icon = this.nIconAtSmoke; } private void TimerRefreshIcon_Tick(object sender, EventArgs e) @@ -7731,13 +7731,13 @@ private void TimerRefreshIcon_Tick(object sender, EventArgs e) private void ContextMenuTabProperty_Opening(object sender, CancelEventArgs e) { // 右クリックの場合はタブ名が設定済。アプリケーションキーの場合は現在のタブを対象とする - if (MyCommon.IsNullOrEmpty(this._rclickTabName) || sender != this.ContextMenuTabProperty) - this._rclickTabName = this.CurrentTabName; + if (MyCommon.IsNullOrEmpty(this.rclickTabName) || sender != this.ContextMenuTabProperty) + this.rclickTabName = this.CurrentTabName; - if (this._statuses == null) return; - if (this._statuses.Tabs == null) return; + if (this.statuses == null) return; + if (this.statuses.Tabs == null) return; - if (!this._statuses.Tabs.TryGetValue(this._rclickTabName, out var tb)) + if (!this.statuses.Tabs.TryGetValue(this.rclickTabName, out var tb)) return; this.NotifyDispMenuItem.Checked = tb.Notify; @@ -7766,12 +7766,12 @@ private void ContextMenuTabProperty_Opening(object sender, CancelEventArgs e) this.UreadManageMenuItem.Checked = tb.UnreadManage; this.UnreadMngTbMenuItem.Checked = tb.UnreadManage; - this.TabMenuControl(this._rclickTabName); + this.TabMenuControl(this.rclickTabName); } private void TabMenuControl(string tabName) { - var tabInfo = this._statuses.GetTabByName(tabName)!; + var tabInfo = this.statuses.GetTabByName(tabName)!; this.FilterEditMenuItem.Enabled = true; this.EditRuleTbMenuItem.Enabled = true; @@ -7815,8 +7815,8 @@ private void ProtectTabMenuItem_Click(object sender, EventArgs e) this.DeleteTabMenuItem.Enabled = !checkState; this.DeleteTbMenuItem.Enabled = !checkState; - if (MyCommon.IsNullOrEmpty(this._rclickTabName)) return; - this._statuses.Tabs[this._rclickTabName].Protected = checkState; + if (MyCommon.IsNullOrEmpty(this.rclickTabName)) return; + this.statuses.Tabs[this.rclickTabName].Protected = checkState; this.SaveConfigsTabs(); } @@ -7826,8 +7826,8 @@ private void UreadManageMenuItem_Click(object sender, EventArgs e) this.UreadManageMenuItem.Checked = ((ToolStripMenuItem)sender).Checked; this.UnreadMngTbMenuItem.Checked = this.UreadManageMenuItem.Checked; - if (MyCommon.IsNullOrEmpty(this._rclickTabName)) return; - this.ChangeTabUnreadManage(this._rclickTabName, this.UreadManageMenuItem.Checked); + if (MyCommon.IsNullOrEmpty(this.rclickTabName)) return; + this.ChangeTabUnreadManage(this.rclickTabName, this.UreadManageMenuItem.Checked); this.SaveConfigsTabs(); } @@ -7838,7 +7838,7 @@ public void ChangeTabUnreadManage(string tabName, bool isManage) if (idx == -1) return; - var tab = this._statuses.Tabs[tabName]; + var tab = this.statuses.Tabs[tabName]; tab.UnreadManage = isManage; if (SettingManager.Common.TabIconDisp) @@ -7866,39 +7866,39 @@ private void NotifyDispMenuItem_Click(object sender, EventArgs e) this.NotifyDispMenuItem.Checked = ((ToolStripMenuItem)sender).Checked; this.NotifyTbMenuItem.Checked = this.NotifyDispMenuItem.Checked; - if (MyCommon.IsNullOrEmpty(this._rclickTabName)) return; + if (MyCommon.IsNullOrEmpty(this.rclickTabName)) return; - this._statuses.Tabs[this._rclickTabName].Notify = this.NotifyDispMenuItem.Checked; + this.statuses.Tabs[this.rclickTabName].Notify = this.NotifyDispMenuItem.Checked; this.SaveConfigsTabs(); } private void SoundFileComboBox_SelectedIndexChanged(object sender, EventArgs e) { - if (this.soundfileListup || MyCommon.IsNullOrEmpty(this._rclickTabName)) return; + if (this.soundfileListup || MyCommon.IsNullOrEmpty(this.rclickTabName)) return; - this._statuses.Tabs[this._rclickTabName].SoundFile = (string)((ToolStripComboBox)sender).SelectedItem; + this.statuses.Tabs[this.rclickTabName].SoundFile = (string)((ToolStripComboBox)sender).SelectedItem; this.SaveConfigsTabs(); } private void DeleteTabMenuItem_Click(object sender, EventArgs e) { - if (MyCommon.IsNullOrEmpty(this._rclickTabName) || sender == this.DeleteTbMenuItem) - this._rclickTabName = this.CurrentTabName; + if (MyCommon.IsNullOrEmpty(this.rclickTabName) || sender == this.DeleteTbMenuItem) + this.rclickTabName = this.CurrentTabName; - this.RemoveSpecifiedTab(this._rclickTabName, true); + this.RemoveSpecifiedTab(this.rclickTabName, true); this.SaveConfigsTabs(); } private void FilterEditMenuItem_Click(object sender, EventArgs e) { - if (MyCommon.IsNullOrEmpty(this._rclickTabName)) this._rclickTabName = this._statuses.HomeTab.TabName; + if (MyCommon.IsNullOrEmpty(this.rclickTabName)) this.rclickTabName = this.statuses.HomeTab.TabName; using (var fltDialog = new FilterDialog()) { fltDialog.Owner = this; - fltDialog.SetCurrent(this._rclickTabName); + fltDialog.SetCurrent(this.rclickTabName); fltDialog.ShowDialog(this); } this.TopMost = SettingManager.Common.AlwaysTop; @@ -7913,7 +7913,7 @@ private async void AddTabMenuItem_Click(object sender, EventArgs e) MyCommon.TabUsageType tabUsage; using (var inputName = new InputTabName()) { - inputName.TabName = this._statuses.MakeTabName("MyTab"); + inputName.TabName = this.statuses.MakeTabName("MyTab"); inputName.IsShowUsage = true; inputName.ShowDialog(); if (inputName.DialogResult == DialogResult.Cancel) return; @@ -7951,7 +7951,7 @@ private async void AddTabMenuItem_Click(object sender, EventArgs e) return; } - if (!this._statuses.AddTab(tab) || !this.AddNewTab(tab, startup: false)) + if (!this.statuses.AddTab(tab) || !this.AddNewTab(tab, startup: false)) { var tmp = string.Format(Properties.Resources.AddTabMenuItem_ClickText1, tabName); MessageBox.Show(tmp, Properties.Resources.AddTabMenuItem_ClickText2, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); @@ -7961,7 +7961,7 @@ private async void AddTabMenuItem_Click(object sender, EventArgs e) // 成功 this.SaveConfigsTabs(); - var tabIndex = this._statuses.Tabs.Count - 1; + var tabIndex = this.statuses.Tabs.Count - 1; if (tabUsage == MyCommon.TabUsageType.PublicSearch) { @@ -8016,20 +8016,20 @@ protected override bool ProcessDialogKey(Keys keyData) { if (this.StatusText.Focused) { - var _NewLine = false; - var _Post = false; + var newLine = false; + var post = false; if (SettingManager.Common.PostCtrlEnter) // Ctrl+Enter投稿時 { if (this.StatusText.Multiline) { - if ((keyData & Keys.Shift) == Keys.Shift && (keyData & Keys.Control) != Keys.Control) _NewLine = true; + if ((keyData & Keys.Shift) == Keys.Shift && (keyData & Keys.Control) != Keys.Control) newLine = true; - if ((keyData & Keys.Control) == Keys.Control) _Post = true; + if ((keyData & Keys.Control) == Keys.Control) post = true; } else { - if ((keyData & Keys.Control) == Keys.Control) _Post = true; + if ((keyData & Keys.Control) == Keys.Control) post = true; } } @@ -8037,13 +8037,13 @@ protected override bool ProcessDialogKey(Keys keyData) { if (this.StatusText.Multiline) { - if ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Shift) != Keys.Shift) _NewLine = true; + if ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Shift) != Keys.Shift) newLine = true; - if ((keyData & Keys.Shift) == Keys.Shift) _Post = true; + if ((keyData & Keys.Shift) == Keys.Shift) post = true; } else { - if ((keyData & Keys.Shift) == Keys.Shift) _Post = true; + if ((keyData & Keys.Shift) == Keys.Shift) post = true; } } @@ -8051,20 +8051,20 @@ protected override bool ProcessDialogKey(Keys keyData) { if (this.StatusText.Multiline) { - if ((keyData & Keys.Shift) == Keys.Shift && (keyData & Keys.Control) != Keys.Control) _NewLine = true; + if ((keyData & Keys.Shift) == Keys.Shift && (keyData & Keys.Control) != Keys.Control) newLine = true; if (((keyData & Keys.Control) != Keys.Control && (keyData & Keys.Shift) != Keys.Shift) || - ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Shift) == Keys.Shift)) _Post = true; + ((keyData & Keys.Control) == Keys.Control && (keyData & Keys.Shift) == Keys.Shift)) post = true; } else { if (((keyData & Keys.Shift) == Keys.Shift) || (((keyData & Keys.Control) != Keys.Control) && - ((keyData & Keys.Shift) != Keys.Shift))) _Post = true; + ((keyData & Keys.Shift) != Keys.Shift))) post = true; } } - if (_NewLine) + if (newLine) { var pos1 = this.StatusText.SelectionStart; if (this.StatusText.SelectionLength > 0) @@ -8075,7 +8075,7 @@ protected override bool ProcessDialogKey(Keys keyData) this.StatusText.SelectionStart = pos1 + Environment.NewLine.Length; // カーソルを改行の次の文字へ移動 return true; } - else if (_Post) + else if (post) { this.PostButton_Click(this.PostButton, EventArgs.Empty); return true; @@ -8224,7 +8224,7 @@ private bool SelectTab([NotNullWhen(true)] out FilterTabModel? tab) tab = null; // 振り分け先タブ選択 - using (var dialog = new TabsDialog(this._statuses)) + using (var dialog = new TabsDialog(this.statuses)) { if (dialog.ShowDialog(this) == DialogResult.Cancel) return false; @@ -8238,7 +8238,7 @@ private bool SelectTab([NotNullWhen(true)] out FilterTabModel? tab) string tabName; using (var inputName = new InputTabName()) { - inputName.TabName = this._statuses.MakeTabName("MyTab"); + inputName.TabName = this.statuses.MakeTabName("MyTab"); inputName.ShowDialog(); if (inputName.DialogResult == DialogResult.Cancel) return false; tabName = inputName.TabName; @@ -8247,7 +8247,7 @@ private bool SelectTab([NotNullWhen(true)] out FilterTabModel? tab) if (!MyCommon.IsNullOrEmpty(tabName)) { var newTab = new FilterTabModel(tabName); - if (!this._statuses.AddTab(newTab) || !this.AddNewTab(newTab, startup: false)) + if (!this.statuses.AddTab(newTab) || !this.AddNewTab(newTab, startup: false)) { var tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText2, tabName); MessageBox.Show(tmp, Properties.Resources.IDRuleMenuItem_ClickText3, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); @@ -8273,8 +8273,8 @@ private void MoveOrCopy(out bool move, out bool mark) { { // 移動するか? - var _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine); - if (MessageBox.Show(_tmp, Properties.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + var tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText4, Environment.NewLine); + if (MessageBox.Show(tmp, Properties.Resources.IDRuleMenuItem_ClickText5, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) move = false; else move = true; @@ -8282,8 +8282,8 @@ private void MoveOrCopy(out bool move, out bool mark) if (!move) { // マークするか? - var _tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText6, Environment.NewLine); - if (MessageBox.Show(_tmp, Properties.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + var tmp = string.Format(Properties.Resources.IDRuleMenuItem_ClickText6, Environment.NewLine); + if (MessageBox.Show(tmp, Properties.Resources.IDRuleMenuItem_ClickText7, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) mark = true; else mark = false; @@ -8316,7 +8316,7 @@ private void SelectAllMenuItem_Click(object sender, EventArgs e) private void MoveMiddle() { - ListViewItem _item; + ListViewItem item; int idx1; int idx2; @@ -8325,17 +8325,17 @@ private void MoveMiddle() var idx = listView.SelectedIndices[0]; - _item = listView.GetItemAt(0, 25); - if (_item == null) + item = listView.GetItemAt(0, 25); + if (item == null) idx1 = 0; else - idx1 = _item.Index; + idx1 = item.Index; - _item = listView.GetItemAt(0, listView.ClientSize.Height - 1); - if (_item == null) + item = listView.GetItemAt(0, listView.ClientSize.Height - 1); + if (item == null) idx2 = listView.VirtualListSize - 1; else - idx2 = _item.Index; + idx2 = item.Index; idx -= Math.Abs(idx1 - idx2) / 2; if (idx < 0) idx = 0; @@ -8381,17 +8381,17 @@ private async void OpenURLMenuItem_Click(object sender, EventArgs e) { // ツイートに含まれる URL が複数ある場合 // => OpenURL を表示しユーザーが選択したリンクを開く - this.UrlDialog.ClearUrl(); + this.urlDialog.ClearUrl(); foreach (var link in links) - this.UrlDialog.AddUrl(link); + this.urlDialog.AddUrl(link); - if (this.UrlDialog.ShowDialog(this) != DialogResult.OK) + if (this.urlDialog.ShowDialog(this) != DialogResult.OK) return; this.TopMost = SettingManager.Common.AlwaysTop; - selectedUrl = this.UrlDialog.SelectedUrl; + selectedUrl = this.urlDialog.SelectedUrl; // Ctrlを押しながらリンクを開いた場合は、設定と逆の動作をするフラグを true としておく isReverseSettings = MyCommon.IsKeyDown(Keys.Control); @@ -8402,8 +8402,8 @@ private async void OpenURLMenuItem_Click(object sender, EventArgs e) private void ClearTabMenuItem_Click(object sender, EventArgs e) { - if (MyCommon.IsNullOrEmpty(this._rclickTabName)) return; - this.ClearTab(this._rclickTabName, true); + if (MyCommon.IsNullOrEmpty(this.rclickTabName)) return; + this.ClearTab(this.rclickTabName, true); } private void ClearTab(string tabName, bool showWarning) @@ -8417,15 +8417,15 @@ private void ClearTab(string tabName, bool showWarning) } } - this._statuses.ClearTabIds(tabName); + this.statuses.ClearTabIds(tabName); if (this.CurrentTabName == tabName) { - this._anchorPost = null; - this._anchorFlag = false; + this.anchorPost = null; + this.anchorFlag = false; this.PurgeListViewItemCache(); } - var tabIndex = this._statuses.Tabs.IndexOf(tabName); + var tabIndex = this.statuses.Tabs.IndexOf(tabName); var tabPage = this.ListTab.TabPages[tabIndex]; tabPage.ImageIndex = -1; @@ -8451,7 +8451,7 @@ private void SetMainWindowTitle() SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver && SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus) { - foreach (var tab in this._statuses.Tabs) + foreach (var tab in this.statuses.Tabs) { ur += tab.UnreadCount; al += tab.AllCount; @@ -8467,17 +8467,17 @@ private void SetMainWindowTitle() ttl.Append("Ver:").Append(MyCommon.GetReadableVersion()); break; case MyCommon.DispTitleEnum.Post: - if (this._history != null && this._history.Count > 1) - ttl.Append(this._history[this._history.Count - 2].Status.Replace("\r\n", " ")); + if (this.history != null && this.history.Count > 1) + ttl.Append(this.history[this.history.Count - 2].Status.Replace("\r\n", " ")); break; case MyCommon.DispTitleEnum.UnreadRepCount: - ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText1, this._statuses.MentionTab.UnreadCount + this._statuses.DirectMessageTab.UnreadCount); + ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText1, this.statuses.MentionTab.UnreadCount + this.statuses.DirectMessageTab.UnreadCount); break; case MyCommon.DispTitleEnum.UnreadAllCount: ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText2, ur); break; case MyCommon.DispTitleEnum.UnreadAllRepCount: - ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText3, ur, this._statuses.MentionTab.UnreadCount + this._statuses.DirectMessageTab.UnreadCount); + ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText3, ur, this.statuses.MentionTab.UnreadCount + this.statuses.DirectMessageTab.UnreadCount); break; case MyCommon.DispTitleEnum.UnreadCountAllCount: ttl.AppendFormat(Properties.Resources.SetMainWindowTitleText4, ur, al); @@ -8502,9 +8502,9 @@ private string GetStatusLabelText() { // ステータス欄にカウント表示 // タブ未読数/タブ発言数 全未読数/総発言数 (未読@+未読DM数) - if (this._statuses == null) return ""; - var tbRep = this._statuses.MentionTab; - var tbDm = this._statuses.DirectMessageTab; + if (this.statuses == null) return ""; + var tbRep = this.statuses.MentionTab; + var tbDm = this.statuses.DirectMessageTab; if (tbRep == null || tbDm == null) return ""; var urat = tbRep.UnreadCount + tbDm.UnreadCount; var ur = 0; @@ -8514,7 +8514,7 @@ private string GetStatusLabelText() var slbl = new StringBuilder(256); try { - foreach (var tab in this._statuses.Tabs) + foreach (var tab in this.statuses.Tabs) { ur += tab.UnreadCount; al += tab.AllCount; @@ -8530,12 +8530,12 @@ private string GetStatusLabelText() return ""; } - this.UnreadCounter = ur; - this.UnreadAtCounter = urat; + this.unreadCounter = ur; + this.unreadAtCounter = urat; - var homeTab = this._statuses.HomeTab; + var homeTab = this.statuses.HomeTab; - slbl.AppendFormat(Properties.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, this._postTimestamps.Count, this._favTimestamps.Count, homeTab.TweetsPerHour); + slbl.AppendFormat(Properties.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, this.postTimestamps.Count, this.favTimestamps.Count, homeTab.TweetsPerHour); if (SettingManager.Common.TimelinePeriod == 0) { slbl.Append(Properties.Resources.SetStatusLabelText2); @@ -8637,22 +8637,22 @@ private void SetNotifyIconText() #if DEBUG ur.Append("(Debug Build)"); #endif - if (this.UnreadCounter != -1 && this.UnreadAtCounter != -1) + if (this.unreadCounter != -1 && this.unreadAtCounter != -1) { ur.Append(" ["); - ur.Append(this.UnreadCounter); + ur.Append(this.unreadCounter); ur.Append("/@"); - ur.Append(this.UnreadAtCounter); + ur.Append(this.unreadAtCounter); ur.Append("]"); } this.NotifyIcon1.Text = ur.ToString(); } - internal void CheckReplyTo(string StatusText) + internal void CheckReplyTo(string statusText) { MatchCollection m; // ハッシュタグの保存 - m = Regex.Matches(StatusText, Twitter.HASHTAG, RegexOptions.IgnoreCase); + m = Regex.Matches(statusText, Twitter.HASHTAG, RegexOptions.IgnoreCase); var hstr = ""; foreach (Match hm in m) { @@ -8669,7 +8669,7 @@ internal void CheckReplyTo(string StatusText) if (!MyCommon.IsNullOrEmpty(hstr)) this.HashMgr.AddHashToHistory(hstr.Trim(), false); // 本当にリプライ先指定すべきかどうかの判定 - m = Regex.Matches(StatusText, "(^|[ -/:-@[-^`{-~])(?@[a-zA-Z0-9_]+)"); + m = Regex.Matches(statusText, "(^|[ -/:-@[-^`{-~])(?@[a-zA-Z0-9_]+)"); if (SettingManager.Common.UseAtIdSupplement) { @@ -8695,15 +8695,15 @@ internal void CheckReplyTo(string StatusText) if (m != null) { var inReplyToScreenName = this.inReplyTo.Value.ScreenName; - if (StatusText.StartsWith("@", StringComparison.Ordinal)) + if (statusText.StartsWith("@", StringComparison.Ordinal)) { - if (StatusText.StartsWith("@" + inReplyToScreenName, StringComparison.Ordinal)) return; + if (statusText.StartsWith("@" + inReplyToScreenName, StringComparison.Ordinal)) return; } else { foreach (Match mid in m) { - if (StatusText.Contains("RT " + mid.Result("${id}") + ":") && mid.Result("${id}") == "@" + inReplyToScreenName) return; + if (statusText.Contains("RT " + mid.Result("${id}") + ":") && mid.Result("${id}") == "@" + inReplyToScreenName) return; } } } @@ -8713,11 +8713,11 @@ internal void CheckReplyTo(string StatusText) private void TweenMain_Resize(object sender, EventArgs e) { - if (!this._initialLayout && SettingManager.Common.MinimizeToTray && this.WindowState == FormWindowState.Minimized) + if (!this.initialLayout && SettingManager.Common.MinimizeToTray && this.WindowState == FormWindowState.Minimized) { this.Visible = false; } - if (this._initialLayout && SettingManager.Local != null && this.WindowState == FormWindowState.Normal && this.Visible) + if (this.initialLayout && SettingManager.Local != null && this.WindowState == FormWindowState.Normal && this.Visible) { // 現在の DPI と設定保存時の DPI との比を取得する var configScaleFactor = SettingManager.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions); @@ -8761,11 +8761,11 @@ private void TweenMain_Resize(object sender, EventArgs e) // Panel2Collapsed は SplitterDistance の設定を終えるまで true にしない this.SplitContainer3.Panel2Collapsed = true; - this._initialLayout = false; + this.initialLayout = false; } if (this.WindowState != FormWindowState.Minimized) { - this._formWindowState = this.WindowState; + this.formWindowState = this.WindowState; } } @@ -8786,7 +8786,7 @@ private void PlaySoundMenuItem_CheckedChanged(object sender, EventArgs e) private void SplitContainer1_SplitterMoved(object sender, SplitterEventArgs e) { - if (this._initialLayout) + if (this.initialLayout) return; int splitterDistance; @@ -8797,7 +8797,7 @@ private void SplitContainer1_SplitterMoved(object sender, SplitterEventArgs e) break; case FormWindowState.Maximized: // 最大化時は、通常時のウィンドウサイズに換算した SplitterDistance を算出する - var normalContainerHeight = this._mySize.Height - this.ToolStripContainer1.TopToolStripPanel.Height - this.ToolStripContainer1.BottomToolStripPanel.Height; + var normalContainerHeight = this.mySize.Height - this.ToolStripContainer1.TopToolStripPanel.Height - this.ToolStripContainer1.BottomToolStripPanel.Height; splitterDistance = this.SplitContainer1.SplitterDistance - (this.SplitContainer1.Height - normalContainerHeight); splitterDistance = Math.Min(splitterDistance, normalContainerHeight - this.SplitContainer1.SplitterWidth - this.SplitContainer1.Panel2MinSize); break; @@ -8805,7 +8805,7 @@ private void SplitContainer1_SplitterMoved(object sender, SplitterEventArgs e) return; } - this._mySpDis = splitterDistance; + this.mySpDis = splitterDistance; this.MarkSettingLocalModified(); } @@ -8819,13 +8819,13 @@ private async Task DoRepliedStatusOpen() await MyCommon.OpenInBrowserAsync(this, MyCommon.GetStatusUrl(currentPost.InReplyToUser, currentPost.InReplyToStatusId.Value)); return; } - if (this._statuses.Posts.TryGetValue(currentPost.InReplyToStatusId.Value, out var repPost)) + if (this.statuses.Posts.TryGetValue(currentPost.InReplyToStatusId.Value, out var repPost)) { MessageBox.Show($"{repPost.ScreenName} / {repPost.Nickname} ({repPost.CreatedAt.ToLocalTimeString()})" + Environment.NewLine + repPost.TextFromApi); } else { - foreach (var tb in this._statuses.GetTabsByType(MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.PublicSearch)) + foreach (var tb in this.statuses.GetTabsByType(MyCommon.TabUsageType.Lists | MyCommon.TabUsageType.PublicSearch)) { if (tb == null || !tb.Contains(currentPost.InReplyToStatusId.Value)) break; repPost = tb.Posts[currentPost.InReplyToStatusId.Value]; @@ -8842,7 +8842,7 @@ private async void RepliedStatusOpenMenuItem_Click(object sender, EventArgs e) private void SplitContainer2_Panel2_Resize(object sender, EventArgs e) { - if (this._initialLayout) + if (this.initialLayout) return; // SettingLocal の反映が完了するまで multiline の判定を行わない var multiline = this.SplitContainer2.Panel2.Height > this.SplitContainer2.Panel2MinSize + 2; @@ -8861,7 +8861,7 @@ private void StatusText_MultilineChanged(object sender, EventArgs e) else this.StatusText.ScrollBars = ScrollBars.None; - if (!this._initialLayout) + if (!this.initialLayout) this.MarkSettingLocalModified(); } @@ -8873,10 +8873,10 @@ private void MultiLineMenuItem_Click(object sender, EventArgs e) SettingManager.Local.StatusMultiline = menuItemChecked; if (menuItemChecked) { - if (this.SplitContainer2.Height - this._mySpDis2 - this.SplitContainer2.SplitterWidth < 0) + if (this.SplitContainer2.Height - this.mySpDis2 - this.SplitContainer2.SplitterWidth < 0) this.SplitContainer2.SplitterDistance = 0; else - this.SplitContainer2.SplitterDistance = this.SplitContainer2.Height - this._mySpDis2 - this.SplitContainer2.SplitterWidth; + this.SplitContainer2.SplitterDistance = this.SplitContainer2.Height - this.mySpDis2 - this.SplitContainer2.SplitterWidth; } else { @@ -8885,9 +8885,9 @@ private void MultiLineMenuItem_Click(object sender, EventArgs e) this.MarkSettingLocalModified(); } - private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) + private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) { - if (Converter_Type == MyCommon.UrlConverter.Bitly || Converter_Type == MyCommon.UrlConverter.Jmp) + if (converterType == MyCommon.UrlConverter.Bitly || converterType == MyCommon.UrlConverter.Jmp) { // OAuth2 アクセストークンまたは API キー (旧方式) のいずれも設定されていなければ短縮しない if (MyCommon.IsNullOrEmpty(SettingManager.Common.BitlyAccessToken) && @@ -8919,23 +8919,23 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) { result = Nicoms.Shorten(tmp); } - else if (Converter_Type != MyCommon.UrlConverter.Nicoms) + else if (converterType != MyCommon.UrlConverter.Nicoms) { // 短縮URL変換 try { var srcUri = new Uri(tmp); - var resultUri = await ShortUrl.Instance.ShortenUrlAsync(Converter_Type, srcUri); + var resultUri = await ShortUrl.Instance.ShortenUrlAsync(converterType, srcUri); result = resultUri.AbsoluteUri; } catch (WebApiException e) { - this.StatusLabel.Text = Converter_Type + ":" + e.Message; + this.StatusLabel.Text = converterType + ":" + e.Message; return false; } catch (UriFormatException e) { - this.StatusLabel.Text = Converter_Type + ":" + e.Message; + this.StatusLabel.Text = converterType + ":" + e.Message; return false; } } @@ -8995,13 +8995,13 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) { result = Nicoms.Shorten(tmp); } - else if (Converter_Type != MyCommon.UrlConverter.Nicoms) + else if (converterType != MyCommon.UrlConverter.Nicoms) { // 短縮URL変換 try { var srcUri = new Uri(tmp); - var resultUri = await ShortUrl.Instance.ShortenUrlAsync(Converter_Type, srcUri); + var resultUri = await ShortUrl.Instance.ShortenUrlAsync(converterType, srcUri); result = resultUri.AbsoluteUri; } catch (HttpRequestException e) @@ -9010,17 +9010,17 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter Converter_Type) // のように長いので「:」が含まれていればそれ以降のみを抽出する var message = e.Message.Split(new[] { ':' }, count: 2).Last(); - this.StatusLabel.Text = Converter_Type + ":" + message; + this.StatusLabel.Text = converterType + ":" + message; continue; } catch (WebApiException e) { - this.StatusLabel.Text = Converter_Type + ":" + e.Message; + this.StatusLabel.Text = converterType + ":" + e.Message; continue; } catch (UriFormatException e) { - this.StatusLabel.Text = Converter_Type + ":" + e.Message; + this.StatusLabel.Text = converterType + ":" + e.Message; continue; } } @@ -9149,7 +9149,7 @@ private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e) var lst = (DetailsListView)sender; if (SettingManager.Local == null) return; - if (this._iconCol) + if (this.iconCol) { SettingManager.Local.Width1 = lst.Columns[0].Width; SettingManager.Local.Width3 = lst.Columns[1].Width; @@ -9203,7 +9203,7 @@ private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e) SettingManager.Local.Width8 = lst.Columns[7].Width; } this.MarkSettingLocalModified(); - this._isColumnChanged = true; + this.isColumnChanged = true; } private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e) @@ -9212,7 +9212,7 @@ private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArg if (SettingManager.Local == null) return; var modified = false; - if (this._iconCol) + if (this.iconCol) { if (SettingManager.Local.Width1 != lst.Columns[0].Width) { @@ -9271,13 +9271,13 @@ private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArg if (modified) { this.MarkSettingLocalModified(); - this._isColumnChanged = true; + this.isColumnChanged = true; } } private void SplitContainer2_SplitterMoved(object sender, SplitterEventArgs e) { - if (this.StatusText.Multiline) this._mySpDis2 = this.StatusText.Height; + if (this.StatusText.Multiline) this.mySpDis2 = this.StatusText.Height; this.MarkSettingLocalModified(); } @@ -9400,7 +9400,7 @@ private void TweenMain_DragOver(object sender, DragEventArgs e) public bool IsNetworkAvailable() { var nw = MyCommon.IsNetworkAvailable(); - this._myStatusOnline = nw; + this.myStatusOnline = nw; return nw; } @@ -9466,28 +9466,28 @@ private async Task OpenInternalUriAsync(Uri uri) } } - private void ListTabSelect(TabPage _tab) + private void ListTabSelect(TabPage tab) { this.SetListProperty(); this.PurgeListViewItemCache(); - this._statuses.SelectTab(_tab.Text); + this.statuses.SelectTab(tab.Text); var listView = this.CurrentListView; - this._anchorPost = null; - this._anchorFlag = false; + this.anchorPost = null; + this.anchorFlag = false; - if (this._iconCol) + if (this.iconCol) { - listView.Columns[1].Text = this.ColumnText[2]; + listView.Columns[1].Text = this.columnText[2]; } else { for (var i = 0; i < listView.Columns.Count; i++) { - listView.Columns[i].Text = this.ColumnText[i]; + listView.Columns[i].Text = this.columnText[i]; } } } @@ -9495,12 +9495,12 @@ private void ListTabSelect(TabPage _tab) private void ListTab_Selecting(object sender, TabControlCancelEventArgs e) => this.ListTabSelect(e.TabPage); - private void SelectListItem(DetailsListView LView, int Index) + private void SelectListItem(DetailsListView lView, int index) { // 単一 var bnd = new Rectangle(); var flg = false; - var item = LView.FocusedItem; + var item = lView.FocusedItem; if (item != null) { bnd = item.Bounds; @@ -9509,46 +9509,46 @@ private void SelectListItem(DetailsListView LView, int Index) do { - LView.SelectedIndices.Clear(); + lView.SelectedIndices.Clear(); } - while (LView.SelectedIndices.Count > 0); - item = LView.Items[Index]; + while (lView.SelectedIndices.Count > 0); + item = lView.Items[index]; item.Selected = true; item.Focused = true; - if (flg) LView.Invalidate(bnd); + if (flg) lView.Invalidate(bnd); } - private void SelectListItem(DetailsListView LView, int[]? Index, int focusedIndex, int selectionMarkIndex) + private void SelectListItem(DetailsListView lView, int[]? index, int focusedIndex, int selectionMarkIndex) { // 複数 var bnd = new Rectangle(); var flg = false; - var item = LView.FocusedItem; + var item = lView.FocusedItem; if (item != null) { bnd = item.Bounds; flg = true; } - if (Index != null) + if (index != null) { - LView.SelectItems(Index); + lView.SelectItems(index); } - if (selectionMarkIndex > -1 && LView.VirtualListSize > selectionMarkIndex) + if (selectionMarkIndex > -1 && lView.VirtualListSize > selectionMarkIndex) { - LView.SelectionMark = selectionMarkIndex; + lView.SelectionMark = selectionMarkIndex; } - if (focusedIndex > -1 && LView.VirtualListSize > focusedIndex) + if (focusedIndex > -1 && lView.VirtualListSize > focusedIndex) { - LView.Items[focusedIndex].Focused = true; + lView.Items[focusedIndex].Focused = true; } - else if (Index != null && Index.Length != 0) + else if (index != null && index.Length != 0) { - LView.Items[Index.Last()].Focused = true; + lView.Items[index.Last()].Focused = true; } - if (flg) LView.Invalidate(bnd); + if (flg) lView.Invalidate(bnd); } private async void TweenMain_Shown(object sender, EventArgs e) @@ -9631,7 +9631,7 @@ private async void TweenMain_Shown(object sender, EventArgs e) await Task.WhenAll(reloadTasks); } - this._initial = false; + this.initial = false; this.timelineScheduler.Enabled = true; } @@ -9660,25 +9660,25 @@ private async Task DoReTweetOfficial(bool isConfirm) if (selectedPosts.Any(x => x.IsProtect)) MessageBox.Show("Protected."); - this._DoFavRetweetFlags = false; + this.doFavRetweetFlags = false; return; } if (selectedPosts.Length > 15) { MessageBox.Show(Properties.Resources.RetweetLimitText); - this._DoFavRetweetFlags = false; + this.doFavRetweetFlags = false; return; } else if (selectedPosts.Length > 1) { - var QuestionText = Properties.Resources.RetweetQuestion2; - if (this._DoFavRetweetFlags) QuestionText = Properties.Resources.FavoriteRetweetQuestionText1; - switch (MessageBox.Show(QuestionText, "Retweet", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)) + var questionText = Properties.Resources.RetweetQuestion2; + if (this.doFavRetweetFlags) questionText = Properties.Resources.FavoriteRetweetQuestionText1; + switch (MessageBox.Show(questionText, "Retweet", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)) { case DialogResult.Cancel: case DialogResult.No: - this._DoFavRetweetFlags = false; + this.doFavRetweetFlags = false; return; } } @@ -9686,11 +9686,11 @@ private async Task DoReTweetOfficial(bool isConfirm) { if (!SettingManager.Common.RetweetNoConfirm) { - var Questiontext = Properties.Resources.RetweetQuestion1; - if (this._DoFavRetweetFlags) Questiontext = Properties.Resources.FavoritesRetweetQuestionText2; - if (isConfirm && MessageBox.Show(Questiontext, "Retweet", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) + var questiontext = Properties.Resources.RetweetQuestion1; + if (this.doFavRetweetFlags) questiontext = Properties.Resources.FavoritesRetweetQuestionText2; + if (isConfirm && MessageBox.Show(questiontext, "Retweet", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) { - this._DoFavRetweetFlags = false; + this.doFavRetweetFlags = false; return; } } @@ -9708,11 +9708,11 @@ private async void ReTweetStripMenuItem_Click(object sender, EventArgs e) private async Task FavoritesRetweetOfficial() { if (!this.ExistCurrentPost) return; - this._DoFavRetweetFlags = true; + this.doFavRetweetFlags = true; var retweetTask = this.DoReTweetOfficial(true); - if (this._DoFavRetweetFlags) + if (this.doFavRetweetFlags) { - this._DoFavRetweetFlags = false; + this.doFavRetweetFlags = false; var favoriteTask = this.FavoriteChange(true, false); await Task.WhenAll(retweetTask, favoriteTask); @@ -9728,11 +9728,11 @@ private async Task FavoritesRetweetUnofficial() var post = this.CurrentPost; if (this.ExistCurrentPost && post != null && !post.IsDm) { - this._DoFavRetweetFlags = true; + this.doFavRetweetFlags = true; var favoriteTask = this.FavoriteChange(true); - if (!post.IsProtect && this._DoFavRetweetFlags) + if (!post.IsProtect && this.doFavRetweetFlags) { - this._DoFavRetweetFlags = false; + this.doFavRetweetFlags = false; this.DoReTweetUnofficial(); } @@ -9842,9 +9842,9 @@ private void TweenMain_Deactivate(object sender, EventArgs e) private void TabRenameMenuItem_Click(object sender, EventArgs e) { - if (MyCommon.IsNullOrEmpty(this._rclickTabName)) return; + if (MyCommon.IsNullOrEmpty(this.rclickTabName)) return; - _ = this.TabRename(this._rclickTabName, out _); + _ = this.TabRename(this.rclickTabName, out _); } private async void BitlyToolStripMenuItem_Click(object sender, EventArgs e) @@ -10185,12 +10185,12 @@ private async void SearchButton_Click(object sender, EventArgs e) var pnl = ((Control)sender).Parent; if (pnl == null) return; var tbName = pnl.Parent.Text; - var tb = (PublicSearchTabModel)this._statuses.Tabs[tbName]; + var tb = (PublicSearchTabModel)this.statuses.Tabs[tbName]; var cmb = (ComboBox)pnl.Controls["comboSearch"]; var cmbLang = (ComboBox)pnl.Controls["comboLang"]; cmb.Text = cmb.Text.Trim(); // 検索式演算子 OR についてのみ大文字しか認識しないので強制的に大文字とする - var Quote = false; + var quote = false; var buf = new StringBuilder(); var c = cmb.Text.ToCharArray(); for (var cnt = 0; cnt < cmb.Text.Length; cnt++) @@ -10202,11 +10202,11 @@ private async void SearchButton_Click(object sender, EventArgs e) } if (c[cnt] == '"') { - Quote = !Quote; + quote = !quote; } else { - if (!Quote && cmb.Text.Substring(cnt, 4).Equals(" or ", StringComparison.OrdinalIgnoreCase)) + if (!quote && cmb.Text.Substring(cnt, 4).Equals(" or ", StringComparison.OrdinalIgnoreCase)) { buf.Append(" OR "); cnt += 3; @@ -10238,7 +10238,7 @@ private async void SearchButton_Click(object sender, EventArgs e) cmb.SelectAll(); this.PurgeListViewItemCache(); listView.VirtualListSize = 0; - this._statuses.ClearTabIds(tbName); + this.statuses.ClearTabIds(tbName); this.SaveConfigsTabs(); // 検索条件の保存 } @@ -10256,11 +10256,11 @@ private async void RefreshMoreStripMenuItem_Click(object sender, EventArgs e) /// 非表示のタブについて -1 が返ることを常に考慮して下さい /// public int GetTabPageIndex(string tabName) - => this._statuses.Tabs.IndexOf(tabName); + => this.statuses.Tabs.IndexOf(tabName); private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) { - if (this._statuses.RemovedTab.Count == 0) + if (this.statuses.RemovedTab.Count == 0) { MessageBox.Show("There isn't removed tab.", "Undo", MessageBoxButtons.OK, MessageBoxIcon.Information); return; @@ -10269,19 +10269,19 @@ private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) { DetailsListView? listView; - var tb = this._statuses.RemovedTab.Pop(); + var tb = this.statuses.RemovedTab.Pop(); if (tb.TabType == MyCommon.TabUsageType.Related) { - var relatedTab = this._statuses.GetTabByType(MyCommon.TabUsageType.Related); + var relatedTab = this.statuses.GetTabByType(MyCommon.TabUsageType.Related); if (relatedTab != null) { // 関連発言なら既存のタブを置き換える tb.TabName = relatedTab.TabName; this.ClearTab(tb.TabName, false); - this._statuses.ReplaceTab(tb); + this.statuses.ReplaceTab(tb); - var tabIndex = this._statuses.Tabs.IndexOf(tb); + var tabIndex = this.statuses.Tabs.IndexOf(tb); var tabPage = this.ListTab.TabPages[tabIndex]; listView = (DetailsListView)tabPage.Tag; this.ListTab.SelectedIndex = tabIndex; @@ -10292,16 +10292,16 @@ private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) var renamed = TabName; for (var i = 2; i <= 100; i++) { - if (!this._statuses.ContainsTab(renamed)) + if (!this.statuses.ContainsTab(renamed)) break; renamed = TabName + i; } tb.TabName = renamed; - this._statuses.AddTab(tb); + this.statuses.AddTab(tb); this.AddNewTab(tb, startup: false); - var tabIndex = this._statuses.Tabs.Count - 1; + var tabIndex = this.statuses.Tabs.Count - 1; var tabPage = this.ListTab.TabPages[tabIndex]; listView = (DetailsListView)tabPage.Tag; @@ -10313,16 +10313,16 @@ private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) var renamed = tb.TabName; for (var i = 1; i < int.MaxValue; i++) { - if (!this._statuses.ContainsTab(renamed)) + if (!this.statuses.ContainsTab(renamed)) break; renamed = tb.TabName + "(" + i + ")"; } tb.TabName = renamed; - this._statuses.AddTab(tb); + this.statuses.AddTab(tb); this.AddNewTab(tb, startup: false); - var tabIndex = this._statuses.Tabs.Count - 1; + var tabIndex = this.statuses.Tabs.Count - 1; var tabPage = this.ListTab.TabPages[tabIndex]; listView = (DetailsListView)tabPage.Tag; @@ -10569,7 +10569,7 @@ public Twitter TwitterInstance private void SplitContainer3_SplitterMoved(object sender, SplitterEventArgs e) { - if (this._initialLayout) + if (this.initialLayout) return; int splitterDistance; @@ -10580,7 +10580,7 @@ private void SplitContainer3_SplitterMoved(object sender, SplitterEventArgs e) break; case FormWindowState.Maximized: // 最大化時は、通常時のウィンドウサイズに換算した SplitterDistance を算出する - var normalContainerWidth = this._mySize.Width - SystemInformation.Border3DSize.Width * 2; + var normalContainerWidth = this.mySize.Width - SystemInformation.Border3DSize.Width * 2; splitterDistance = this.SplitContainer3.SplitterDistance - (this.SplitContainer3.Width - normalContainerWidth); splitterDistance = Math.Min(splitterDistance, normalContainerWidth - this.SplitContainer3.SplitterWidth - this.SplitContainer3.Panel2MinSize); break; @@ -10588,13 +10588,13 @@ private void SplitContainer3_SplitterMoved(object sender, SplitterEventArgs e) return; } - this._mySpDis3 = splitterDistance; + this.mySpDis3 = splitterDistance; this.MarkSettingLocalModified(); } private void MenuItemEdit_DropDownOpening(object sender, EventArgs e) { - if (this._statuses.RemovedTab.Count == 0) + if (this.statuses.RemovedTab.Count == 0) { this.UndoRemoveTabMenuItem.Enabled = false; } @@ -10632,11 +10632,11 @@ private void NotifyIcon1_MouseMove(object sender, MouseEventArgs e) private async void UserStatusToolStripMenuItem_Click(object sender, EventArgs e) => await this.ShowUserStatus(this.CurrentPost?.ScreenName ?? ""); - private async Task DoShowUserStatus(string id, bool ShowInputDialog) + private async Task DoShowUserStatus(string id, bool showInputDialog) { TwitterUser? user = null; - if (ShowInputDialog) + if (showInputDialog) { using var inputName = new InputTabName(); inputName.FormTitle = "Show UserStatus"; @@ -10687,8 +10687,8 @@ private async Task DoShowUserStatus(TwitterUser user) await showUserTask; } - internal Task ShowUserStatus(string id, bool ShowInputDialog) - => this.DoShowUserStatus(id, ShowInputDialog); + internal Task ShowUserStatus(string id, bool showInputDialog) + => this.DoShowUserStatus(id, showInputDialog); internal Task ShowUserStatus(string id) => this.DoShowUserStatus(id, true); @@ -10743,10 +10743,10 @@ private async void RtCountMenuItem_Click(object sender, EventArgs e) MessageBox.Show(status.RetweetCount + Properties.Resources.RtCountText1); } - private readonly HookGlobalHotkey _hookGlobalHotkey; + private readonly HookGlobalHotkey hookGlobalHotkey; public TweenMain() { - this._hookGlobalHotkey = new HookGlobalHotkey(this); + this.hookGlobalHotkey = new HookGlobalHotkey(this); // この呼び出しは、Windows フォーム デザイナで必要です。 this.InitializeComponent(); @@ -10761,7 +10761,7 @@ public TweenMain() this.tweetDetailsView.Owner = this; - this._hookGlobalHotkey.HotkeyPressed += this.HookGlobalHotkey_HotkeyPressed; + this.hookGlobalHotkey.HotkeyPressed += this.HookGlobalHotkey_HotkeyPressed; this.gh.NotifyClicked += this.GrowlHelper_Callback; // メイリオフォント指定時にタブの最小幅が広くなる問題の対策 @@ -10950,7 +10950,7 @@ private async void ShowRelatedStatusesMenuItem_Click(object sender, EventArgs e) /// 名前の重複が多すぎてタブを作成できない場合 public async Task OpenRelatedTab(long statusId) { - var post = this._statuses[statusId]; + var post = this.statuses[statusId]; if (post == null) { try @@ -10974,13 +10974,13 @@ public async Task OpenRelatedTab(long statusId) /// 名前の重複が多すぎてタブを作成できない場合 private async Task OpenRelatedTab(PostClass post) { - var tabRelated = this._statuses.GetTabByType(); + var tabRelated = this.statuses.GetTabByType(); if (tabRelated != null) { this.RemoveSpecifiedTab(tabRelated.TabName, confirm: false); } - var tabName = this._statuses.MakeTabName("Related Tweets"); + var tabName = this.statuses.MakeTabName("Related Tweets"); tabRelated = new RelatedPostsTabModel(tabName, post) { @@ -10988,14 +10988,14 @@ private async Task OpenRelatedTab(PostClass post) Notify = false, }; - this._statuses.AddTab(tabRelated); + this.statuses.AddTab(tabRelated); this.AddNewTab(tabRelated, startup: false); - this.ListTab.SelectedIndex = this._statuses.Tabs.IndexOf(tabName); + this.ListTab.SelectedIndex = this.statuses.Tabs.IndexOf(tabName); await this.RefreshTabAsync(tabRelated); - var tabIndex = this._statuses.Tabs.IndexOf(tabRelated.TabName); + var tabIndex = this.statuses.Tabs.IndexOf(tabRelated.TabName); if (tabIndex != -1) { @@ -11017,8 +11017,8 @@ private async Task OpenRelatedTab(PostClass post) private void CacheInfoMenuItem_Click(object sender, EventArgs e) { var buf = new StringBuilder(); - buf.AppendFormat("キャッシュエントリ保持数 : {0}" + Environment.NewLine, this.IconCache.CacheCount); - buf.AppendFormat("キャッシュエントリ破棄数 : {0}" + Environment.NewLine, this.IconCache.CacheRemoveCount); + buf.AppendFormat("キャッシュエントリ保持数 : {0}" + Environment.NewLine, this.iconCache.CacheCount); + buf.AppendFormat("キャッシュエントリ破棄数 : {0}" + Environment.NewLine, this.iconCache.CacheRemoveCount); MessageBox.Show(buf.ToString(), "アイコンキャッシュ使用状況"); } @@ -11233,12 +11233,12 @@ private void ChangeListViewIconSize(MyCommon.IconSizes iconSize) { if (SettingManager.Common.IconSize == iconSize) return; - var oldIconCol = this._iconCol; + var oldIconCol = this.iconCol; SettingManager.Common.IconSize = iconSize; this.ApplyListViewIconSize(iconSize); - if (this._iconCol != oldIconCol) + if (this.iconCol != oldIconCol) { foreach (TabPage tp in this.ListTab.TabPages) { diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 024b790b4..7dcdd7758 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -69,7 +69,7 @@ public partial class TweetDetailsView : UserControl public event EventHandler? StatusChanged; /// 展開時の .StatusText を保持するフィールド - private string _postBrowserStatusText = ""; + private string postBrowserStatusText = ""; public TweetDetailsView() { @@ -389,25 +389,25 @@ private async Task DoTranslation(string str) private async Task DoSearchToolStrip(string url) { // 発言詳細で「選択文字列で検索」(選択文字列取得) - var _selText = this.PostBrowser.GetSelectedText(); + var selText = this.PostBrowser.GetSelectedText(); - if (_selText != null) + if (selText != null) { if (url == Properties.Resources.SearchItem4Url) { // 公式検索 - this.Owner.AddNewTabForSearch(_selText); + this.Owner.AddNewTabForSearch(selText); return; } - var tmp = string.Format(url, Uri.EscapeDataString(_selText)); + var tmp = string.Format(url, Uri.EscapeDataString(selText)); await MyCommon.OpenInBrowserAsync(this, tmp); } } private string? GetUserId() { - var m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/(#!/)?(?[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$"); + var m = Regex.Match(this.postBrowserStatusText, @"^https?://twitter.com/(#!/)?(?[a-zA-Z0-9_]+)(/status(es)?/[0-9]+)?$"); if (m.Success && this.Owner.IsTwitterId(m.Result("${ScreenName}"))) return m.Result("${ScreenName}"); else @@ -465,8 +465,8 @@ private async void PostBrowser_Navigating(object sender, WebBrowserNavigatingEve private async void PostBrowser_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) { - var KeyRes = this.Owner.CommonKeyDown(e.KeyData, FocusedControl.PostBrowser, out var asyncTask); - if (KeyRes) + var keyRes = this.Owner.CommonKeyDown(e.KeyData, FocusedControl.PostBrowser, out var asyncTask); + if (keyRes) { e.IsInputKey = true; } @@ -749,7 +749,7 @@ private void ContextMenuPostBrowser_Opening(object ender, CancelEventArgs e) // URLコピーの項目の表示/非表示 if (this.PostBrowser.StatusText.StartsWith("http", StringComparison.Ordinal)) { - this._postBrowserStatusText = this.PostBrowser.StatusText; + this.postBrowserStatusText = this.PostBrowser.StatusText; var name = this.GetUserId(); this.UrlCopyContextMenuItem.Enabled = true; if (name != null) @@ -775,14 +775,14 @@ private void ContextMenuPostBrowser_Opening(object ender, CancelEventArgs e) this.SearchAtPostsDetailToolStripMenuItem.Enabled = false; } - if (Regex.IsMatch(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23")) + if (Regex.IsMatch(this.postBrowserStatusText, @"^https?://twitter.com/search\?q=%23")) this.UseHashtagMenuItem.Enabled = true; else this.UseHashtagMenuItem.Enabled = false; } else { - this._postBrowserStatusText = ""; + this.postBrowserStatusText = ""; this.UrlCopyContextMenuItem.Enabled = false; this.FollowContextMenuItem.Enabled = false; this.RemoveContextMenuItem.Enabled = false; @@ -795,8 +795,8 @@ private void ContextMenuPostBrowser_Opening(object ender, CancelEventArgs e) this.ListManageUserContextToolStripMenuItem.Enabled = false; } // 文字列選択されていないときは選択文字列関係の項目を非表示に - var _selText = this.PostBrowser.GetSelectedText(); - if (_selText == null) + var selText = this.PostBrowser.GetSelectedText(); + if (selText == null) { this.SelectionSearchContextMenuItem.Enabled = false; this.SelectionCopyContextMenuItem.Enabled = false; @@ -841,13 +841,13 @@ private async void SearchPublicSearchContextMenuItem_Click(object sender, EventA private void CurrentTabToolStripMenuItem_Click(object sender, EventArgs e) { // 発言詳細の選択文字列で現在のタブを検索 - var _selText = this.PostBrowser.GetSelectedText(); + var selText = this.PostBrowser.GetSelectedText(); - if (_selText != null) + if (selText != null) { var searchOptions = new SearchWordDialog.SearchOptions( SearchWordDialog.SearchType.Timeline, - _selText, + selText, newTab: false, caseSensitive: false, useRegex: false); @@ -865,10 +865,10 @@ private void CurrentTabToolStripMenuItem_Click(object sender, EventArgs e) private void SelectionCopyContextMenuItem_Click(object sender, EventArgs e) { // 発言詳細で「選択文字列をコピー」 - var _selText = this.PostBrowser.GetSelectedText(); + var selText = this.PostBrowser.GetSelectedText(); try { - Clipboard.SetDataObject(_selText, false, 5, 100); + Clipboard.SetDataObject(selText, false, 5, 100); } catch (Exception ex) { @@ -882,7 +882,7 @@ private void UrlCopyContextMenuItem_Click(object sender, EventArgs e) { foreach (var link in this.PostBrowser.Document.Links.Cast()) { - if (link.GetAttribute("href") == this._postBrowserStatusText) + if (link.GetAttribute("href") == this.postBrowserStatusText) { var linkStr = link.GetAttribute("title"); if (MyCommon.IsNullOrEmpty(linkStr)) @@ -893,7 +893,7 @@ private void UrlCopyContextMenuItem_Click(object sender, EventArgs e) } } - Clipboard.SetDataObject(this._postBrowserStatusText, false, 5, 100); + Clipboard.SetDataObject(this.postBrowserStatusText, false, 5, 100); } catch (Exception ex) { @@ -991,7 +991,7 @@ private void ListManageUserContextToolStripMenuItem_Click(object sender, EventAr private void UseHashtagMenuItem_Click(object sender, EventArgs e) { - var m = Regex.Match(this._postBrowserStatusText, @"^https?://twitter.com/search\?q=%23(?.+)$"); + var m = Regex.Match(this.postBrowserStatusText, @"^https?://twitter.com/search\?q=%23(?.+)$"); if (m.Success) this.Owner.SetPermanentHashtag(Uri.UnescapeDataString(m.Groups["hash"].Value)); } diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 17680f49b..770be4fdc 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -162,12 +162,12 @@ public class Twitter : IDisposable public bool GetNoRetweetSuccess { get; private set; } = false; delegate void GetIconImageDelegate(PostClass post); - private readonly object LockObj = new object(); + private readonly object lockObj = new object(); private ISet followerId = new HashSet(); private long[] noRTId = Array.Empty(); // プロパティからアクセスされる共通情報 - private readonly List _hashList = new List(); + private readonly List hashList = new List(); private string? nextCursorDirectMessage = null; @@ -398,7 +398,7 @@ await this.CreateDirectMessagesEventFromJson(messageEventSingle, read: true) .ConfigureAwait(false); // 二重取得回避 - lock (this.LockObj) + lock (this.lockObj) { if (TabInformations.GetInstance().ContainsKey(status.Id)) return null; @@ -850,7 +850,7 @@ public static IEnumerable GetQuoteTweetStatusIds(IEnumerable urls) minimumId = status.Id; // 二重取得回避 - lock (this.LockObj) + lock (this.lockObj) { if (tab == null) { @@ -891,7 +891,7 @@ public static IEnumerable GetQuoteTweetStatusIds(IEnumerable urls) if (!more && status.Id > tab.SinceId) tab.SinceId = status.Id; // 二重取得回避 - lock (this.LockObj) + lock (this.lockObj) { if (tab.Contains(status.Id)) continue; } @@ -918,7 +918,7 @@ public static IEnumerable GetQuoteTweetStatusIds(IEnumerable urls) minimumId = status.Id; // 二重取得回避 - lock (this.LockObj) + lock (this.lockObj) { if (favTab.Contains(status.Id)) continue; } @@ -1029,19 +1029,19 @@ public async Task GetRelatedResult(bool read, RelatedPostsTabModel tab) var text = targetPost.Text; var ma = Twitter.StatusUrlRegex.Matches(text).Cast() .Concat(Twitter.ThirdPartyStatusUrlRegex.Matches(text).Cast()); - foreach (var _match in ma) + foreach (var match in ma) { - if (long.TryParse(_match.Groups["StatusId"].Value, out var _statusId)) + if (long.TryParse(match.Groups["StatusId"].Value, out var statusId)) { - if (relPosts.ContainsKey(_statusId)) + if (relPosts.ContainsKey(statusId)) continue; - var p = TabInformations.GetInstance()[_statusId]; + var p = TabInformations.GetInstance()[statusId]; if (p == null) { try { - p = await this.GetStatusApi(read, _statusId) + p = await this.GetStatusApi(read, statusId) .ConfigureAwait(false); } catch (WebApiException ex) @@ -1494,22 +1494,22 @@ await this.Api.ListsMembersShow(listId, user) } } - private void ExtractEntities(TwitterEntities? entities, List<(long UserId, string ScreenName)> AtList, List media) + private void ExtractEntities(TwitterEntities? entities, List<(long UserId, string ScreenName)> atList, List media) { if (entities != null) { if (entities.Hashtags != null) { - lock (this.LockObj) + lock (this.lockObj) { - this._hashList.AddRange(entities.Hashtags.Select(x => "#" + x.Text)); + this.hashList.AddRange(entities.Hashtags.Select(x => "#" + x.Text)); } } if (entities.UserMentions != null) { foreach (var ent in entities.UserMentions) { - AtList.Add((ent.Id, ent.ScreenName)); + atList.Add((ent.Id, ent.ScreenName)); } } if (entities.Media != null) @@ -1648,10 +1648,10 @@ public async Task RefreshMuteUserIdsAsync() public string[] GetHashList() { string[] hashArray; - lock (this.LockObj) + lock (this.lockObj) { - hashArray = this._hashList.ToArray(); - this._hashList.Clear(); + hashArray = this.hashList.ToArray(); + this.hashList.Clear(); } return hashArray; } diff --git a/OpenTween/UserInfoDialog.cs b/OpenTween/UserInfoDialog.cs index 0cdc1f608..826f40532 100644 --- a/OpenTween/UserInfoDialog.cs +++ b/OpenTween/UserInfoDialog.cs @@ -49,7 +49,7 @@ namespace OpenTween { public partial class UserInfoDialog : OTBaseForm { - private TwitterUser _displayUser = null!; + private TwitterUser displayUser = null!; private CancellationTokenSource? cancellationTokenSource = null; private readonly TweenMain mainForm; @@ -90,14 +90,14 @@ public async Task ShowUserAsync(TwitterUser user) if (this.IsDisposed) return; - if (user == null || user == this._displayUser) + if (user == null || user == this.displayUser) return; this.CancelLoading(); var cancellationToken = this.cancellationTokenSource!.Token; - this._displayUser = user; + this.displayUser = user; this.LabelId.Text = user.IdStr; this.LabelScreenName.Text = user.ScreenName; @@ -354,7 +354,7 @@ private async void ButtonFollow_Click(object sender, EventArgs e) { try { - await this.twitterApi.FriendshipsCreate(this._displayUser.ScreenName) + await this.twitterApi.FriendshipsCreate(this.displayUser.ScreenName) .IgnoreResponse(); } catch (WebApiException ex) @@ -373,7 +373,7 @@ await this.twitterApi.FriendshipsCreate(this._displayUser.ScreenName) private async void ButtonUnFollow_Click(object sender, EventArgs e) { if (MessageBox.Show( - this._displayUser.ScreenName + Properties.Resources.ButtonUnFollow_ClickText1, + this.displayUser.ScreenName + Properties.Resources.ButtonUnFollow_ClickText1, Properties.Resources.ButtonUnFollow_ClickText2, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, @@ -383,7 +383,7 @@ private async void ButtonUnFollow_Click(object sender, EventArgs e) { try { - await this.twitterApi.FriendshipsDestroy(this._displayUser.ScreenName) + await this.twitterApi.FriendshipsDestroy(this.displayUser.ScreenName) .IgnoreResponse(); } catch (WebApiException ex) @@ -459,30 +459,30 @@ private async void LinkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEve => 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"); private async void ButtonSearchPosts_Click(object sender, EventArgs e) - => await this.mainForm.AddNewTabForUserTimeline(this._displayUser.ScreenName); + => await this.mainForm.AddNewTabForUserTimeline(this.displayUser.ScreenName); private async void UserPicture_Click(object sender, EventArgs e) { - var imageUrl = this._displayUser.ProfileImageUrlHttps; + var imageUrl = this.displayUser.ProfileImageUrlHttps; imageUrl = imageUrl.Remove(imageUrl.LastIndexOf("_normal", StringComparison.Ordinal), 7); await MyCommon.OpenInBrowserAsync(this, imageUrl); } - private bool IsEditing = false; - private string ButtonEditText = ""; + private bool isEditing = false; + private string buttonEditText = ""; private async void ButtonEdit_Click(object sender, EventArgs e) { // 自分以外のプロフィールは変更できない - if (this.twitterApi.CurrentUserId != this._displayUser.Id) + if (this.twitterApi.CurrentUserId != this.displayUser.Id) return; using (ControlTransaction.Disabled(this.ButtonEdit)) { - if (!this.IsEditing) + if (!this.isEditing) { - this.ButtonEditText = this.ButtonEdit.Text; + this.buttonEditText = this.ButtonEdit.Text; this.ButtonEdit.Text = Properties.Resources.UserInfoButtonEdit_ClickText1; this.TextBoxName.Text = this.LabelName.Text; @@ -495,12 +495,12 @@ private async void ButtonEdit_Click(object sender, EventArgs e) this.TextBoxLocation.Visible = true; this.LabelLocation.Visible = false; - this.TextBoxWeb.Text = this._displayUser.Url; + this.TextBoxWeb.Text = this.displayUser.Url; this.TextBoxWeb.Enabled = true; this.TextBoxWeb.Visible = true; this.LinkLabelWeb.Visible = false; - this.TextBoxDescription.Text = this._displayUser.Description; + this.TextBoxDescription.Text = this.displayUser.Description; this.TextBoxDescription.Enabled = true; this.TextBoxDescription.Visible = true; this.DescriptionBrowser.Visible = false; @@ -508,7 +508,7 @@ private async void ButtonEdit_Click(object sender, EventArgs e) this.TextBoxName.Focus(); this.TextBoxName.Select(this.TextBoxName.Text.Length, 0); - this.IsEditing = true; + this.isEditing = true; } else { @@ -553,9 +553,9 @@ private async void ButtonEdit_Click(object sender, EventArgs e) this.TextBoxDescription.Visible = false; this.DescriptionBrowser.Visible = true; - this.ButtonEdit.Text = this.ButtonEditText; + this.ButtonEdit.Text = this.buttonEditText; - this.IsEditing = false; + this.isEditing = false; if (showUserTask != null) await showUserTask; @@ -582,7 +582,7 @@ await this.twitterApi.AccountUpdateProfileImage(mediaItem) try { - var user = await this.twitterApi.UsersShow(this._displayUser.ScreenName); + var user = await this.twitterApi.UsersShow(this.displayUser.ScreenName); if (user != null) await this.ShowUserAsync(user); @@ -620,7 +620,7 @@ private async void ChangeIconToolStripMenuItem_Click(object sender, EventArgs e) private async void ButtonBlock_Click(object sender, EventArgs e) { if (MessageBox.Show( - this._displayUser.ScreenName + Properties.Resources.ButtonBlock_ClickText1, + this.displayUser.ScreenName + Properties.Resources.ButtonBlock_ClickText1, Properties.Resources.ButtonBlock_ClickText2, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, @@ -630,7 +630,7 @@ private async void ButtonBlock_Click(object sender, EventArgs e) { try { - await this.twitterApi.BlocksCreate(this._displayUser.ScreenName) + await this.twitterApi.BlocksCreate(this.displayUser.ScreenName) .IgnoreResponse(); } catch (WebApiException ex) @@ -647,7 +647,7 @@ await this.twitterApi.BlocksCreate(this._displayUser.ScreenName) private async void ButtonReportSpam_Click(object sender, EventArgs e) { if (MessageBox.Show( - this._displayUser.ScreenName + Properties.Resources.ButtonReportSpam_ClickText1, + this.displayUser.ScreenName + Properties.Resources.ButtonReportSpam_ClickText1, Properties.Resources.ButtonReportSpam_ClickText2, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, @@ -657,7 +657,7 @@ private async void ButtonReportSpam_Click(object sender, EventArgs e) { try { - await this.twitterApi.UsersReportSpam(this._displayUser.ScreenName) + await this.twitterApi.UsersReportSpam(this.displayUser.ScreenName) .IgnoreResponse(); } catch (WebApiException ex) @@ -674,7 +674,7 @@ await this.twitterApi.UsersReportSpam(this._displayUser.ScreenName) private async void ButtonBlockDestroy_Click(object sender, EventArgs e) { if (MessageBox.Show( - this._displayUser.ScreenName + Properties.Resources.ButtonBlockDestroy_ClickText1, + this.displayUser.ScreenName + Properties.Resources.ButtonBlockDestroy_ClickText1, Properties.Resources.ButtonBlockDestroy_ClickText2, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, @@ -684,7 +684,7 @@ private async void ButtonBlockDestroy_Click(object sender, EventArgs e) { try { - await this.twitterApi.BlocksDestroy(this._displayUser.ScreenName) + await this.twitterApi.BlocksDestroy(this.displayUser.ScreenName) .IgnoreResponse(); } catch (WebApiException ex) diff --git a/OpenTween/WebBrowserController.cs b/OpenTween/WebBrowserController.cs index c7207e843..40158dc6f 100644 --- a/OpenTween/WebBrowserController.cs +++ b/OpenTween/WebBrowserController.cs @@ -290,18 +290,18 @@ public enum POLICY public POLICY SecurityPolicy { get; set; } = 0; - public InternetSecurityManager(WebBrowser _WebBrowser) + public InternetSecurityManager(WebBrowser webBrowser) { // ActiveXコントロール取得 - _WebBrowser.Url = new Uri("about:blank"); // ActiveXを初期化する + webBrowser.Url = new Uri("about:blank"); // ActiveXを初期化する do { Thread.Sleep(100); Application.DoEvents(); - } while (_WebBrowser.ReadyState != WebBrowserReadyState.Complete); + } while (webBrowser.ReadyState != WebBrowserReadyState.Complete); - this.ocx = _WebBrowser.ActiveXInstance; + this.ocx = webBrowser.ActiveXInstance; // IServiceProvider.QueryService() を使って IProfferService を取得 this.ocxServiceProvider = (WebBrowserAPI.IServiceProvider)this.ocx; From c4b13711ed3addf5f2767953eb98cba9213f5bdf Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 06:16:00 +0900 Subject: [PATCH 102/402] =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=BC=E3=83=AB?= =?UTF-8?q?=E3=83=89=E5=90=8D=E3=81=AB=E3=82=A2=E3=83=B3=E3=83=80=E3=83=BC?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=92=E5=85=A5=E3=82=8C=E3=81=AA=E3=81=84?= =?UTF-8?q?=20(SA1310)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Api/ApiLimitTest.cs | 4 ++-- OpenTween.Tests/Api/TwitterApiStatusTest.cs | 12 +++++----- OpenTween.Tests/DateTimeUtcTest.cs | 12 +++++----- OpenTween.Tests/MyCommonTest.cs | 12 +++++----- .../Services/SimpleThumbnailService.cs | 12 +++++----- OpenTween/Tween.cs | 8 +++---- OpenTween/TweetExtractor.cs | 2 +- OpenTween/Twitter.cs | 22 +++++++++---------- OpenTween/WebBrowserController.cs | 1 + 9 files changed, 43 insertions(+), 42 deletions(-) diff --git a/OpenTween.Tests/Api/ApiLimitTest.cs b/OpenTween.Tests/Api/ApiLimitTest.cs index e2e53d1d6..0c0b1d534 100644 --- a/OpenTween.Tests/Api/ApiLimitTest.cs +++ b/OpenTween.Tests/Api/ApiLimitTest.cs @@ -30,7 +30,7 @@ namespace OpenTween.Api { public class ApiLimitTest { - public static readonly TheoryData Equals_TestCase = new TheoryData + public static readonly TheoryData EqualsTestCase = new TheoryData { { new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)), true }, { new ApiLimit(350, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)), false }, @@ -41,7 +41,7 @@ public class ApiLimitTest }; [Theory] - [MemberData(nameof(Equals_TestCase))] + [MemberData(nameof(EqualsTestCase))] public void EqualsTest(object? obj2, bool expected) { var obj1 = new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)); diff --git a/OpenTween.Tests/Api/TwitterApiStatusTest.cs b/OpenTween.Tests/Api/TwitterApiStatusTest.cs index e9511b952..a1132e7b1 100644 --- a/OpenTween.Tests/Api/TwitterApiStatusTest.cs +++ b/OpenTween.Tests/Api/TwitterApiStatusTest.cs @@ -49,7 +49,7 @@ public void ResetTest() Assert.Equal(TwitterApiAccessLevel.Anonymous, apiStatus.AccessLevel); } - public static readonly TheoryData, ApiLimit?> ParseRateLimit_TestCase = new TheoryData, ApiLimit?> + public static readonly TheoryData, ApiLimit?> ParseRateLimitTestCase = new TheoryData, ApiLimit?> { { new Dictionary { @@ -85,14 +85,14 @@ public void ResetTest() }; [Theory] - [MemberData(nameof(ParseRateLimit_TestCase))] + [MemberData(nameof(ParseRateLimitTestCase))] public void ParseRateLimitTest(IDictionary header, ApiLimit? expected) { var limit = TwitterApiStatus.ParseRateLimit(header, "X-RateLimit-"); Assert.Equal(expected, limit); } - public static readonly TheoryData, ApiLimit?> ParseMediaRateLimit_TestCase = new TheoryData, ApiLimit?> + public static readonly TheoryData, ApiLimit?> ParseMediaRateLimitTestCase = new TheoryData, ApiLimit?> { { new Dictionary { @@ -120,14 +120,14 @@ public void ParseRateLimitTest(IDictionary header, ApiLimit? exp }; [Theory] - [MemberData(nameof(ParseMediaRateLimit_TestCase))] + [MemberData(nameof(ParseMediaRateLimitTestCase))] public void ParseMediaRateLimitTest(IDictionary header, ApiLimit? expected) { var limit = TwitterApiStatus.ParseRateLimit(header, "X-MediaRateLimit-"); Assert.Equal(expected, limit); } - public static readonly TheoryData, TwitterApiAccessLevel?> ParseAccessLevel_TestCase = new TheoryData, TwitterApiAccessLevel?> + public static readonly TheoryData, TwitterApiAccessLevel?> ParseAccessLevelTestCase = new TheoryData, TwitterApiAccessLevel?> { { new Dictionary { { "X-Access-Level", "read" } }, @@ -152,7 +152,7 @@ public void ParseMediaRateLimitTest(IDictionary header, ApiLimit }; [Theory] - [MemberData(nameof(ParseAccessLevel_TestCase))] + [MemberData(nameof(ParseAccessLevelTestCase))] public void ParseAccessLevelTest(IDictionary header, TwitterApiAccessLevel? expected) { var accessLevel = TwitterApiStatus.ParseAccessLevel(header, "X-Access-Level"); diff --git a/OpenTween.Tests/DateTimeUtcTest.cs b/OpenTween.Tests/DateTimeUtcTest.cs index 9ed6cd291..532deec73 100644 --- a/OpenTween.Tests/DateTimeUtcTest.cs +++ b/OpenTween.Tests/DateTimeUtcTest.cs @@ -269,7 +269,7 @@ public void FromUnixTime_Test() utc.ToDateTimeUnsafe()); } - public static readonly TheoryData Parse_Test_Fixtures = new TheoryData + public static readonly TheoryData ParseTestFixtures = new TheoryData { { "2018-05-06T11:22:33.111", new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, { "2018-05-06T11:22:33.111+00:00", new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, @@ -277,7 +277,7 @@ public void FromUnixTime_Test() }; [Theory] - [MemberData(nameof(Parse_Test_Fixtures))] + [MemberData(nameof(ParseTestFixtures))] public void Parse_Test(string input, DateTimeUtc expected) => Assert.Equal(expected, DateTimeUtc.Parse(input, DateTimeFormatInfo.InvariantInfo)); @@ -285,7 +285,7 @@ public void Parse_Test(string input, DateTimeUtc expected) public void Parse_ErrorTest() => Assert.Throws(() => DateTimeUtc.Parse("### INVALID ###", DateTimeFormatInfo.InvariantInfo)); - public static readonly TheoryData TryParse_Test_Fixtures = new TheoryData + public static readonly TheoryData TryParseTestFixtures = new TheoryData { { "2018-05-06T11:22:33.111", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, { "2018-05-06T11:22:33.111+00:00", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, @@ -294,7 +294,7 @@ public void Parse_ErrorTest() }; [Theory] - [MemberData(nameof(TryParse_Test_Fixtures))] + [MemberData(nameof(TryParseTestFixtures))] public void TryParse_Test(string input, bool expectedParsed, DateTimeUtc expectedResult) { var parsed = DateTimeUtc.TryParse(input, DateTimeFormatInfo.InvariantInfo, out var result); @@ -303,7 +303,7 @@ public void TryParse_Test(string input, bool expectedParsed, DateTimeUtc expecte Assert.Equal(expectedResult, result); } - public static readonly TheoryData TryParseExact_Test_Fixtures = new TheoryData + public static readonly TheoryData TryParseExactTestFixtures = new TheoryData { { "2018-05-06 11:22:33.111", "yyyy-MM-dd HH:mm:ss.fff", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, { "2018-05-06 11:22:33.111 +00:00", "yyyy-MM-dd HH:mm:ss.fff zzz", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, @@ -313,7 +313,7 @@ public void TryParse_Test(string input, bool expectedParsed, DateTimeUtc expecte }; [Theory] - [MemberData(nameof(TryParseExact_Test_Fixtures))] + [MemberData(nameof(TryParseExactTestFixtures))] public void TryParseExact_Test(string input, string format, bool expectedParsed, DateTimeUtc expectedResult) { var parsed = DateTimeUtc.TryParseExact(input, new[] { format }, DateTimeFormatInfo.InvariantInfo, out var result); diff --git a/OpenTween.Tests/MyCommonTest.cs b/OpenTween.Tests/MyCommonTest.cs index 55fed128e..497aab04d 100644 --- a/OpenTween.Tests/MyCommonTest.cs +++ b/OpenTween.Tests/MyCommonTest.cs @@ -104,14 +104,14 @@ public void ResizeBytesArrayTest(byte[] bytes, int size, byte[] expected) public void IsAnimatedGifTest(string filename, bool expected) => Assert.Equal(expected, MyCommon.IsAnimatedGif(filename)); - public static readonly TheoryData DateTimeParse_TestCase = new TheoryData + public static readonly TheoryData DateTimeParseTestCase = new TheoryData { { "Sun Nov 25 06:10:00 +00:00 2012", new DateTimeUtc(2012, 11, 25, 6, 10, 0) }, { "Sun, 25 Nov 2012 06:10:00 +00:00", new DateTimeUtc(2012, 11, 25, 6, 10, 0) }, }; [Theory] - [MemberData(nameof(DateTimeParse_TestCase))] + [MemberData(nameof(DateTimeParseTestCase))] public void DateTimeParseTest(string date, DateTimeUtc excepted) => Assert.Equal(excepted, MyCommon.DateTimeParse(date)); @@ -124,7 +124,7 @@ public struct JsonData [DataMember(Name = "body")] public string Body { get; set; } } - public static readonly TheoryData CreateDataFromJson_TestCase = new TheoryData + public static readonly TheoryData CreateDataFromJsonTestCase = new TheoryData { { @"{""id"":""1"", ""body"":""hogehoge""}", @@ -133,7 +133,7 @@ public struct JsonData }; [Theory] - [MemberData(nameof(CreateDataFromJson_TestCase))] + [MemberData(nameof(CreateDataFromJsonTestCase))] public void CreateDataFromJsonTest(string json, T expected) => Assert.Equal(expected, MyCommon.CreateDataFromJson(json)); @@ -185,7 +185,7 @@ public void ReplaceAppNameTest(string str, string excepted) public void GetReadableVersionTest(string fileVersion, string expected) => Assert.Equal(expected, MyCommon.GetReadableVersion(fileVersion)); - public static readonly TheoryData GetStatusUrlTest1_TestCase = new TheoryData + public static readonly TheoryData GetStatusUrlTest1TestCase = new TheoryData { { new PostClass { StatusId = 249493863826350080L, ScreenName = "Favstar_LM", RetweetedId = null, RetweetedBy = null }, @@ -198,7 +198,7 @@ public void GetReadableVersionTest(string fileVersion, string expected) }; [Theory] - [MemberData(nameof(GetStatusUrlTest1_TestCase))] + [MemberData(nameof(GetStatusUrlTest1TestCase))] public void GetStatusUrlTest1(PostClass post, string expected) => Assert.Equal(expected, MyCommon.GetStatusUrl(post)); diff --git a/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs b/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs index 36154b7ac..90269350e 100644 --- a/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs @@ -39,8 +39,8 @@ namespace OpenTween.Thumbnail.Services class SimpleThumbnailService : IThumbnailService { protected Regex regex; - protected string thumb_replacement; - protected string? fullsize_replacement; + protected string thumbReplacement; + protected string? fullsizeReplacement; public SimpleThumbnailService(string pattern, string replacement) : this(pattern, replacement, null) @@ -55,8 +55,8 @@ public SimpleThumbnailService(string pattern, string replacement, string? file_r public SimpleThumbnailService(Regex regex, string replacement, string? file_replacement) { this.regex = regex; - this.thumb_replacement = replacement; - this.fullsize_replacement = file_replacement; + this.thumbReplacement = replacement; + this.fullsizeReplacement = file_replacement; } public override Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) @@ -71,14 +71,14 @@ public SimpleThumbnailService(Regex regex, string replacement, string? file_repl MediaPageUrl = url, ThumbnailImageUrl = thumbnailUrl, TooltipText = null, - FullSizeImageUrl = this.ReplaceUrl(url, this.fullsize_replacement) + FullSizeImageUrl = this.ReplaceUrl(url, this.fullsizeReplacement) }; }, token); } protected string? ReplaceUrl(string url) - => this.ReplaceUrl(url, this.thumb_replacement); + => this.ReplaceUrl(url, this.thumbReplacement); protected string? ReplaceUrl(string url, string? replacement) { diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 2316bc415..6a9e446aa 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -349,8 +349,8 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ private bool isColumnChanged = false; - private const int MAX_WORKER_THREADS = 20; - private readonly SemaphoreSlim workerSemaphore = new SemaphoreSlim(MAX_WORKER_THREADS); + private const int MaxWorderThreads = 20; + private readonly SemaphoreSlim workerSemaphore = new SemaphoreSlim(MaxWorderThreads); private readonly CancellationTokenSource workerCts = new CancellationTokenSource(); private readonly IProgress workerProgress = null!; @@ -7671,7 +7671,7 @@ void EnableTasktrayAnimation() void DisableTasktrayAnimation() => this.TimerRefreshIcon.Enabled = false; - var busyTasks = this.workerSemaphore.CurrentCount != MAX_WORKER_THREADS; + var busyTasks = this.workerSemaphore.CurrentCount != MaxWorderThreads; if (busyTasks) { this.iconCnt += 1; @@ -8652,7 +8652,7 @@ internal void CheckReplyTo(string statusText) { MatchCollection m; // ハッシュタグの保存 - m = Regex.Matches(statusText, Twitter.HASHTAG, RegexOptions.IgnoreCase); + m = Regex.Matches(statusText, Twitter.Hashtag, RegexOptions.IgnoreCase); var hstr = ""; foreach (Match hm in m) { diff --git a/OpenTween/TweetExtractor.cs b/OpenTween/TweetExtractor.cs index ed5dc607d..f26eccd7e 100644 --- a/OpenTween/TweetExtractor.cs +++ b/OpenTween/TweetExtractor.cs @@ -142,7 +142,7 @@ public static IEnumerable ExtractMentionEntities(string te /// public static IEnumerable ExtractHashtagEntities(string text) { - var matches = Regex.Matches(text, Twitter.HASHTAG); + var matches = Regex.Matches(text, Twitter.Hashtag); foreach (var match in matches.Cast()) { var groupHashtagSharp = match.Groups[2]; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 770be4fdc..a37d13b76 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -72,14 +72,14 @@ public class Twitter : IDisposable // permissions and limitations under the License. // Hashtag用正規表現 - private const string LATIN_ACCENTS = @"\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0100-\u024f\u0253\u0254\u0256\u0257\u0259\u025b\u0263\u0268\u026f\u0272\u0289\u028b\u02bb\u1e00-\u1eff"; - private const string NON_LATIN_HASHTAG_CHARS = @"\u0400-\u04ff\u0500-\u0527\u1100-\u11ff\u3130-\u3185\uA960-\uA97F\uAC00-\uD7AF\uD7B0-\uD7FF"; - private const string CJ_HASHTAG_CHARACTERS = @"\u30A1-\u30FA\u30FC\u3005\uFF66-\uFF9F\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\u3041-\u309A\u3400-\u4DBF\p{IsCJKUnifiedIdeographs}"; - private const string HASHTAG_BOUNDARY = @"^|$|\s|「|」|。|\.|!"; - private const string HASHTAG_ALPHA = "[A-Za-z_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; - private const string HASHTAG_ALPHANUMERIC = "[A-Za-z0-9_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; - private const string HASHTAG_TERMINATOR = "[^A-Za-z0-9_" + LATIN_ACCENTS + NON_LATIN_HASHTAG_CHARS + CJ_HASHTAG_CHARACTERS + "]"; - public const string HASHTAG = "(" + HASHTAG_BOUNDARY + ")(#|#)(" + HASHTAG_ALPHANUMERIC + "*" + HASHTAG_ALPHA + HASHTAG_ALPHANUMERIC + "*)(?=" + HASHTAG_TERMINATOR + "|" + HASHTAG_BOUNDARY + ")"; + private const string LatinAccents = @"\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0100-\u024f\u0253\u0254\u0256\u0257\u0259\u025b\u0263\u0268\u026f\u0272\u0289\u028b\u02bb\u1e00-\u1eff"; + private const string NonLatinHashtagChars = @"\u0400-\u04ff\u0500-\u0527\u1100-\u11ff\u3130-\u3185\uA960-\uA97F\uAC00-\uD7AF\uD7B0-\uD7FF"; + private const string CJHashtagCharacters = @"\u30A1-\u30FA\u30FC\u3005\uFF66-\uFF9F\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\u3041-\u309A\u3400-\u4DBF\p{IsCJKUnifiedIdeographs}"; + private const string HashtagBoundary = @"^|$|\s|「|」|。|\.|!"; + private const string HashtagAlpha = "[A-Za-z_" + LatinAccents + NonLatinHashtagChars + CJHashtagCharacters + "]"; + private const string HashtagAlphanumeric = "[A-Za-z0-9_" + LatinAccents + NonLatinHashtagChars + CJHashtagCharacters + "]"; + private const string HashtagTerminator = "[^A-Za-z0-9_" + LatinAccents + NonLatinHashtagChars + CJHashtagCharacters + "]"; + public const string Hashtag = "(" + HashtagBoundary + ")(#|#)(" + HashtagAlphanumeric + "*" + HashtagAlpha + HashtagAlphanumeric + "*)(?=" + HashtagTerminator + "|" + HashtagBoundary + ")"; // URL正規表現 private const string UrlValidPrecedingChars = @"(?:[^A-Za-z0-9@@$##\ufffe\ufeff\uffff\u202a-\u202e]|^)"; public const string UrlInvalidWithoutProtocolPrecedingChars = @"[-_./]$"; @@ -91,13 +91,13 @@ public class Twitter : IDisposable private const string UrlValidCCTLD = @"(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))"; private const string UrlValidPunycode = @"(?:xn--[0-9a-z]+)"; private const string UrlValidDomain = @"(?" + UrlValidSubdomain + "*" + UrlValidDomainName + "(?:" + UrlValidGTLD + "|" + UrlValidCCTLD + ")|" + UrlValidPunycode + ")"; - public const string UrlValidAsciiDomain = @"(?:(?:[a-z0-9" + LATIN_ACCENTS + @"]+)\.)+(?:" + UrlValidGTLD + "|" + UrlValidCCTLD + "|" + UrlValidPunycode + ")"; + public const string UrlValidAsciiDomain = @"(?:(?:[a-z0-9" + LatinAccents + @"]+)\.)+(?:" + UrlValidGTLD + "|" + UrlValidCCTLD + "|" + UrlValidPunycode + ")"; public const string UrlInvalidShortDomain = "^" + UrlValidDomainName + UrlValidCCTLD + "$"; private const string UrlValidPortNumber = @"[0-9]+"; - private const string UrlValidGeneralPathChars = @"[a-z0-9!*';:=+,.$/%#\[\]\-_~|&" + LATIN_ACCENTS + "]"; + private const string UrlValidGeneralPathChars = @"[a-z0-9!*';:=+,.$/%#\[\]\-_~|&" + LatinAccents + "]"; private const string UrlBalanceParens = @"(?:\(" + UrlValidGeneralPathChars + @"+\))"; - private const string UrlValidPathEndingChars = @"(?:[+\-a-z0-9=_#/" + LATIN_ACCENTS + "]|" + UrlBalanceParens + ")"; + private const string UrlValidPathEndingChars = @"(?:[+\-a-z0-9=_#/" + LatinAccents + "]|" + UrlBalanceParens + ")"; private const string Pth = "(?:" + "(?:" + UrlValidGeneralPathChars + "*" + diff --git a/OpenTween/WebBrowserController.cs b/OpenTween/WebBrowserController.cs index 40158dc6f..16775229f 100644 --- a/OpenTween/WebBrowserController.cs +++ b/OpenTween/WebBrowserController.cs @@ -25,6 +25,7 @@ // Boston, MA 02110-1301, USA. #nullable enable +#pragma warning disable SA1310 using System; using System.Collections.Generic; From 4502748a44b4b5b421b8aa3f4b2a520725f8be2b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 07:16:09 +0900 Subject: [PATCH 103/402] =?UTF-8?q?=E3=82=A2=E3=82=AF=E3=82=BB=E3=82=B9?= =?UTF-8?q?=E4=BF=AE=E9=A3=BE=E5=AD=90=E3=82=92=E7=9C=81=E7=95=A5=E3=81=97?= =?UTF-8?q?=E3=81=AA=E3=81=84=20(SA1400)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Connection/LazyJsonTest.cs | 2 +- OpenTween.Tests/Models/PostClassTest.cs | 6 +++--- OpenTween.Tests/Models/TabInformationTest.cs | 2 +- OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs | 2 +- .../Thumbnail/Services/MetaThumbnailServiceTest.cs | 2 +- OpenTween.Tests/Thumbnail/Services/TinamiTest.cs | 2 +- OpenTween.Tests/ToolStripAPIGaugeTest.cs | 2 +- OpenTween.Tests/TweetThumbnailTest.cs | 4 ++-- OpenTween/ApplicationEvents.cs | 2 +- OpenTween/LRUCacheDictionary.cs | 2 +- OpenTween/Models/TabUsageTypeExt.cs | 6 +++--- OpenTween/Thumbnail/MapThumb.cs | 2 +- OpenTween/Thumbnail/MapThumbGoogle.cs | 2 +- OpenTween/Thumbnail/MapThumbOSM.cs | 2 +- OpenTween/Thumbnail/Services/FoursquareCheckin.cs | 2 +- OpenTween/Thumbnail/Services/IThumbnailService.cs | 2 +- OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs | 2 +- OpenTween/Thumbnail/Services/MetaThumbnailService.cs | 2 +- OpenTween/Thumbnail/Services/Nicovideo.cs | 2 +- OpenTween/Thumbnail/Services/PbsTwimgCom.cs | 2 +- OpenTween/Thumbnail/Services/Pixiv.cs | 2 +- OpenTween/Thumbnail/Services/SimpleThumbnailService.cs | 2 +- OpenTween/Thumbnail/Services/Tinami.cs | 2 +- OpenTween/Thumbnail/Services/TonTwitterCom.cs | 2 +- OpenTween/Thumbnail/Services/Tumblr.cs | 2 +- OpenTween/Thumbnail/Services/TwitterComVideo.cs | 2 +- OpenTween/Thumbnail/Services/Vimeo.cs | 2 +- OpenTween/Thumbnail/Services/Youtube.cs | 2 +- OpenTween/Thumbnail/ThumbnailGenerator.cs | 2 +- OpenTween/ToolStripLabelHistory.cs | 2 +- OpenTween/Twitter.cs | 2 +- OpenTween/WebBrowserController.cs | 2 +- 32 files changed, 37 insertions(+), 37 deletions(-) diff --git a/OpenTween.Tests/Connection/LazyJsonTest.cs b/OpenTween.Tests/Connection/LazyJsonTest.cs index 242797fdc..862b83dda 100644 --- a/OpenTween.Tests/Connection/LazyJsonTest.cs +++ b/OpenTween.Tests/Connection/LazyJsonTest.cs @@ -92,7 +92,7 @@ await Task.FromResult(lazyJson) Assert.True(bodyStream.IsDisposed); } - class InvalidStream : Stream + private class InvalidStream : Stream { public bool IsDisposed { get; private set; } = false; diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index 4ecbaf303..6d3b38aa7 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -32,7 +32,7 @@ namespace OpenTween.Models { public class PostClassTest { - class PostClassGroup + private class PostClassGroup { private Dictionary testCases; public PostClassGroup(params TestPostClass[] postClasses) @@ -46,7 +46,7 @@ public PostClassGroup(params TestPostClass[] postClasses) } public PostClass this[long id] => this.testCases[id]; } - class TestPostClass : PostClass + private class TestPostClass : PostClass { public PostClassGroup? Group; protected override PostClass RetweetSource @@ -397,7 +397,7 @@ public void ConvertToOriginalPost_ErrorTest() Assert.Throws(() => post.ConvertToOriginalPost()); } - class FakeExpandedUrlInfo : PostClass.ExpandedUrlInfo + private class FakeExpandedUrlInfo : PostClass.ExpandedUrlInfo { public TaskCompletionSource FakeResult = new TaskCompletionSource(); diff --git a/OpenTween.Tests/Models/TabInformationTest.cs b/OpenTween.Tests/Models/TabInformationTest.cs index 380305c6c..7f1f834d5 100644 --- a/OpenTween.Tests/Models/TabInformationTest.cs +++ b/OpenTween.Tests/Models/TabInformationTest.cs @@ -830,7 +830,7 @@ public void FilterAll_ExcludeReplyFilterTest() Assert.True(this.tabinfo[200L]!.IsExcludeReply); } - class TestPostFilterRule : PostFilterRule + private class TestPostFilterRule : PostFilterRule { public static PostFilterRule Create(Func filterDelegate) { diff --git a/OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs b/OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs index a29364ad2..6031fbed9 100644 --- a/OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/ImgAzyobuziNetTest.cs @@ -37,7 +37,7 @@ namespace OpenTween.Thumbnail.Services { public class ImgAzyobuziNetTest { - class TestImgAzyobuziNet : ImgAzyobuziNet + private class TestImgAzyobuziNet : ImgAzyobuziNet { public TestImgAzyobuziNet() : this(new[] { "http://img.azyobuzi.net/api/" }) diff --git a/OpenTween.Tests/Thumbnail/Services/MetaThumbnailServiceTest.cs b/OpenTween.Tests/Thumbnail/Services/MetaThumbnailServiceTest.cs index 9dec5fc5e..2e30ba675 100644 --- a/OpenTween.Tests/Thumbnail/Services/MetaThumbnailServiceTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/MetaThumbnailServiceTest.cs @@ -36,7 +36,7 @@ namespace OpenTween.Thumbnail.Services { public class MetaThumbnailServiceTest { - class TestMetaThumbnailService : MetaThumbnailService + private class TestMetaThumbnailService : MetaThumbnailService { public string FakeHtml { get; set; } = ""; diff --git a/OpenTween.Tests/Thumbnail/Services/TinamiTest.cs b/OpenTween.Tests/Thumbnail/Services/TinamiTest.cs index a7b51e0ba..d2d1c9a46 100644 --- a/OpenTween.Tests/Thumbnail/Services/TinamiTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/TinamiTest.cs @@ -38,7 +38,7 @@ namespace OpenTween.Thumbnail.Services { public class TinamiTest { - class TestTinami : Tinami + private class TestTinami : Tinami { public string FakeXml { get; set; } = ""; diff --git a/OpenTween.Tests/ToolStripAPIGaugeTest.cs b/OpenTween.Tests/ToolStripAPIGaugeTest.cs index c8535b70e..c93fd0495 100644 --- a/OpenTween.Tests/ToolStripAPIGaugeTest.cs +++ b/OpenTween.Tests/ToolStripAPIGaugeTest.cs @@ -158,7 +158,7 @@ public void TextTest() } } - class TestToolStripAPIGauge : ToolStripAPIGauge + private class TestToolStripAPIGauge : ToolStripAPIGauge { public DateTimeUtc DateTimeNow = DateTimeUtc.Now; diff --git a/OpenTween.Tests/TweetThumbnailTest.cs b/OpenTween.Tests/TweetThumbnailTest.cs index 4aefa50ed..2e14a01f5 100644 --- a/OpenTween.Tests/TweetThumbnailTest.cs +++ b/OpenTween.Tests/TweetThumbnailTest.cs @@ -41,7 +41,7 @@ namespace OpenTween { public class TweetThumbnailTest { - class TestThumbnailService : IThumbnailService + private class TestThumbnailService : IThumbnailService { private readonly Regex regex; private readonly string replaceUrl; @@ -71,7 +71,7 @@ public TestThumbnailService(string pattern, string replaceUrl, string? replaceTo }; } - class MockThumbnailInfo : ThumbnailInfo + private class MockThumbnailInfo : ThumbnailInfo { public override Task LoadThumbnailImageAsync(HttpClient http, CancellationToken cancellationToken) => Task.FromResult(TestUtils.CreateDummyImage()); diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index e7ff30a6b..17a41ae47 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -61,7 +61,7 @@ internal class MyApplication /// アプリケーションのメイン エントリ ポイントです。 /// [STAThread] - static int Main(string[] args) + public static int Main(string[] args) { WarnIfApiKeyError(); WarnIfRunAsAdministrator(); diff --git a/OpenTween/LRUCacheDictionary.cs b/OpenTween/LRUCacheDictionary.cs index 75858a022..cac25a8d6 100644 --- a/OpenTween/LRUCacheDictionary.cs +++ b/OpenTween/LRUCacheDictionary.cs @@ -33,7 +33,7 @@ namespace OpenTween /// /// LRU によるキャッシュを行うための辞書クラス /// - class LRUCacheDictionary : IDictionary + public class LRUCacheDictionary : IDictionary { /// /// 保持するアイテムの個数 diff --git a/OpenTween/Models/TabUsageTypeExt.cs b/OpenTween/Models/TabUsageTypeExt.cs index 318f9d7f1..3f85fe44a 100644 --- a/OpenTween/Models/TabUsageTypeExt.cs +++ b/OpenTween/Models/TabUsageTypeExt.cs @@ -34,19 +34,19 @@ namespace OpenTween.Models /// public static class TabUsageTypeExt { - const MyCommon.TabUsageType DefaultTabTypeMask = + private const MyCommon.TabUsageType DefaultTabTypeMask = MyCommon.TabUsageType.Home | MyCommon.TabUsageType.Mentions | MyCommon.TabUsageType.DirectMessage | MyCommon.TabUsageType.Favorites | MyCommon.TabUsageType.Mute; - const MyCommon.TabUsageType DistributableTabTypeMask = + private const MyCommon.TabUsageType DistributableTabTypeMask = MyCommon.TabUsageType.Mentions | MyCommon.TabUsageType.UserDefined | MyCommon.TabUsageType.Mute; - const MyCommon.TabUsageType InnerStorageTabTypeMask = + private const MyCommon.TabUsageType InnerStorageTabTypeMask = MyCommon.TabUsageType.DirectMessage | MyCommon.TabUsageType.PublicSearch | MyCommon.TabUsageType.Lists | diff --git a/OpenTween/Thumbnail/MapThumb.cs b/OpenTween/Thumbnail/MapThumb.cs index 03bbaaef3..cb4a1b0a6 100644 --- a/OpenTween/Thumbnail/MapThumb.cs +++ b/OpenTween/Thumbnail/MapThumb.cs @@ -44,7 +44,7 @@ public enum MapProvider GoogleMaps, } - abstract class MapThumb + public abstract class MapThumb { public abstract Task GetThumbnailInfoAsync(PostClass.StatusGeo geo); diff --git a/OpenTween/Thumbnail/MapThumbGoogle.cs b/OpenTween/Thumbnail/MapThumbGoogle.cs index ac1861c9e..622ed7d4a 100644 --- a/OpenTween/Thumbnail/MapThumbGoogle.cs +++ b/OpenTween/Thumbnail/MapThumbGoogle.cs @@ -32,7 +32,7 @@ namespace OpenTween.Thumbnail { - class MapThumbGoogle : MapThumb + public class MapThumbGoogle : MapThumb { public override Task GetThumbnailInfoAsync(PostClass.StatusGeo geo) { diff --git a/OpenTween/Thumbnail/MapThumbOSM.cs b/OpenTween/Thumbnail/MapThumbOSM.cs index 89d85912a..e9319ddc3 100644 --- a/OpenTween/Thumbnail/MapThumbOSM.cs +++ b/OpenTween/Thumbnail/MapThumbOSM.cs @@ -34,7 +34,7 @@ namespace OpenTween.Thumbnail { - class MapThumbOSM : MapThumb + public class MapThumbOSM : MapThumb { public override Task GetThumbnailInfoAsync(PostClass.StatusGeo geo) { diff --git a/OpenTween/Thumbnail/Services/FoursquareCheckin.cs b/OpenTween/Thumbnail/Services/FoursquareCheckin.cs index 908219c21..4ff71bdff 100644 --- a/OpenTween/Thumbnail/Services/FoursquareCheckin.cs +++ b/OpenTween/Thumbnail/Services/FoursquareCheckin.cs @@ -38,7 +38,7 @@ namespace OpenTween.Thumbnail.Services { - class FoursquareCheckin : IThumbnailService + public class FoursquareCheckin : IThumbnailService { public static readonly Regex UrlPatternRegex = new Regex(@"^https?://www\.swarmapp\.com/c/(?[0-9a-zA-Z]+)"); diff --git a/OpenTween/Thumbnail/Services/IThumbnailService.cs b/OpenTween/Thumbnail/Services/IThumbnailService.cs index a2d970e42..f7e6ed559 100644 --- a/OpenTween/Thumbnail/Services/IThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/IThumbnailService.cs @@ -31,7 +31,7 @@ namespace OpenTween.Thumbnail.Services { - abstract class IThumbnailService + public abstract class IThumbnailService { public abstract Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token); } diff --git a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs index 7a2113a15..bc47e9d8e 100644 --- a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs +++ b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs @@ -36,7 +36,7 @@ namespace OpenTween.Thumbnail.Services { - class ImgAzyobuziNet : IThumbnailService, IDisposable + public class ImgAzyobuziNet : IThumbnailService, IDisposable { protected string[] apiHosts = { "https://img.azyobuzi.net/api/", diff --git a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs index d899076b8..88646ab36 100644 --- a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs @@ -38,7 +38,7 @@ namespace OpenTween.Thumbnail.Services /// /// og:image や twitter:image をスクレイピングしてサムネイルURLを抽出する /// - class MetaThumbnailService : IThumbnailService + public class MetaThumbnailService : IThumbnailService { protected static Regex[] metaPatterns = { diff --git a/OpenTween/Thumbnail/Services/Nicovideo.cs b/OpenTween/Thumbnail/Services/Nicovideo.cs index 8fa39a4b7..7ea67c891 100644 --- a/OpenTween/Thumbnail/Services/Nicovideo.cs +++ b/OpenTween/Thumbnail/Services/Nicovideo.cs @@ -42,7 +42,7 @@ namespace OpenTween.Thumbnail.Services { - class Nicovideo : IThumbnailService + public class Nicovideo : IThumbnailService { public static readonly Regex UrlPatternRegex = new Regex(@"^https?://(?:(www|ext)\.nicovideo\.jp/watch|nico\.ms)/(?(?:sm|nm)?[0-9]+)(\?.+)?$"); diff --git a/OpenTween/Thumbnail/Services/PbsTwimgCom.cs b/OpenTween/Thumbnail/Services/PbsTwimgCom.cs index b05440e0f..8fe3f21f4 100644 --- a/OpenTween/Thumbnail/Services/PbsTwimgCom.cs +++ b/OpenTween/Thumbnail/Services/PbsTwimgCom.cs @@ -32,7 +32,7 @@ namespace OpenTween.Thumbnail.Services { - class PbsTwimgCom : IThumbnailService + public class PbsTwimgCom : IThumbnailService { public static readonly Regex ModernUrlPattern = new Regex(@"^(?https?://pbs\.twimg\.com/[^:.]+)\?([^&]+?&)?format=(?[A-Za-z]+)"); diff --git a/OpenTween/Thumbnail/Services/Pixiv.cs b/OpenTween/Thumbnail/Services/Pixiv.cs index a8f233a93..0f6ea02d8 100644 --- a/OpenTween/Thumbnail/Services/Pixiv.cs +++ b/OpenTween/Thumbnail/Services/Pixiv.cs @@ -35,7 +35,7 @@ namespace OpenTween.Thumbnail.Services { - class Pixiv : MetaThumbnailService + public class Pixiv : MetaThumbnailService { public static readonly string UrlPattern = @"^https?://(www|touch)\.pixiv\.net/(member_illust|index)\.php\?(?=.*mode=(medium|big))(?=.*illust_id=(?[0-9]+)).*$"; diff --git a/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs b/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs index 90269350e..26b4399d2 100644 --- a/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs @@ -36,7 +36,7 @@ namespace OpenTween.Thumbnail.Services /// /// 正規表現によるURLの単純な置換でサムネイルURLを生成する /// - class SimpleThumbnailService : IThumbnailService + public class SimpleThumbnailService : IThumbnailService { protected Regex regex; protected string thumbReplacement; diff --git a/OpenTween/Thumbnail/Services/Tinami.cs b/OpenTween/Thumbnail/Services/Tinami.cs index a53d744c1..b6a502c3c 100644 --- a/OpenTween/Thumbnail/Services/Tinami.cs +++ b/OpenTween/Thumbnail/Services/Tinami.cs @@ -37,7 +37,7 @@ namespace OpenTween.Thumbnail.Services { - class Tinami : IThumbnailService + public class Tinami : IThumbnailService { public static readonly Regex UrlPatternRegex = new Regex(@"^https?://www\.tinami\.com/view/(?\d+)$"); diff --git a/OpenTween/Thumbnail/Services/TonTwitterCom.cs b/OpenTween/Thumbnail/Services/TonTwitterCom.cs index ceb49bed3..80fe74fe3 100644 --- a/OpenTween/Thumbnail/Services/TonTwitterCom.cs +++ b/OpenTween/Thumbnail/Services/TonTwitterCom.cs @@ -38,7 +38,7 @@ namespace OpenTween.Thumbnail.Services /// /// Twitter の DM に添付された画像をサムネイル表示するためのクラス /// - class TonTwitterCom : IThumbnailService + public class TonTwitterCom : IThumbnailService { internal static Func? GetApiConnection; diff --git a/OpenTween/Thumbnail/Services/Tumblr.cs b/OpenTween/Thumbnail/Services/Tumblr.cs index fdcf87751..8de69086a 100644 --- a/OpenTween/Thumbnail/Services/Tumblr.cs +++ b/OpenTween/Thumbnail/Services/Tumblr.cs @@ -38,7 +38,7 @@ namespace OpenTween.Thumbnail.Services { - class Tumblr : IThumbnailService + public class Tumblr : IThumbnailService { public static readonly Regex UrlPatternRegex = new Regex(@"^https?://(?[^.]+\.tumblr\.com|tumblr\.[^.]+\.[^.]+)/post/(?[0-9]+)(/.*)?"); diff --git a/OpenTween/Thumbnail/Services/TwitterComVideo.cs b/OpenTween/Thumbnail/Services/TwitterComVideo.cs index d9c1bd470..881bd5d80 100644 --- a/OpenTween/Thumbnail/Services/TwitterComVideo.cs +++ b/OpenTween/Thumbnail/Services/TwitterComVideo.cs @@ -36,7 +36,7 @@ namespace OpenTween.Thumbnail.Services /// /// サムネイル用URLと動画用URLを用意する /// - class TwitterComVideo : MetaThumbnailService + public class TwitterComVideo : MetaThumbnailService { public static readonly string UrlPattern = @"^https?://amp\.twimg\.com/v/.*$"; diff --git a/OpenTween/Thumbnail/Services/Vimeo.cs b/OpenTween/Thumbnail/Services/Vimeo.cs index 4ce914084..991b7d07e 100644 --- a/OpenTween/Thumbnail/Services/Vimeo.cs +++ b/OpenTween/Thumbnail/Services/Vimeo.cs @@ -39,7 +39,7 @@ namespace OpenTween.Thumbnail.Services { - class Vimeo : IThumbnailService + public class Vimeo : IThumbnailService { public static readonly Regex UrlPatternRegex = new Regex(@"https?://vimeo\.com/(?[0-9]+)"); diff --git a/OpenTween/Thumbnail/Services/Youtube.cs b/OpenTween/Thumbnail/Services/Youtube.cs index 8af3a0899..4577f97ff 100644 --- a/OpenTween/Thumbnail/Services/Youtube.cs +++ b/OpenTween/Thumbnail/Services/Youtube.cs @@ -37,7 +37,7 @@ namespace OpenTween.Thumbnail.Services { - class Youtube : IThumbnailService + public class Youtube : IThumbnailService { public static readonly Regex UrlPatternRegex = new Regex(@"^https?://(?:(?:(?:m|www|music|gaming)\.)?youtube\.com/(?:watch\?(?:[^#]*&)?v=|embed/|shorts/)|youtu\.be/)(?[\w\-]+)"); diff --git a/OpenTween/Thumbnail/ThumbnailGenerator.cs b/OpenTween/Thumbnail/ThumbnailGenerator.cs index 74b93ec2d..9264d343a 100644 --- a/OpenTween/Thumbnail/ThumbnailGenerator.cs +++ b/OpenTween/Thumbnail/ThumbnailGenerator.cs @@ -34,7 +34,7 @@ namespace OpenTween.Thumbnail { - class ThumbnailGenerator + public class ThumbnailGenerator { public static readonly Regex InstagramPattern = new Regex( @"^https?://(?:instagram.com|instagr\.am|i\.instagram\.com|www\.instagram\.com)/([^/]+/)?p/(?[^/]+)/(\?.*)?$", diff --git a/OpenTween/ToolStripLabelHistory.cs b/OpenTween/ToolStripLabelHistory.cs index 1206520dc..51238fc43 100644 --- a/OpenTween/ToolStripLabelHistory.cs +++ b/OpenTween/ToolStripLabelHistory.cs @@ -74,7 +74,7 @@ public override string ToString() private readonly LinkedList logs; - const int MAXCNT = 20; + private const int MAXCNT = 20; public override string Text { diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index a37d13b76..853ad4889 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -161,7 +161,7 @@ public class Twitter : IDisposable public bool GetFollowersSuccess { get; private set; } = false; public bool GetNoRetweetSuccess { get; private set; } = false; - delegate void GetIconImageDelegate(PostClass post); + private delegate void GetIconImageDelegate(PostClass post); private readonly object lockObj = new object(); private ISet followerId = new HashSet(); private long[] noRTId = Array.Empty(); diff --git a/OpenTween/WebBrowserController.cs b/OpenTween/WebBrowserController.cs index 16775229f..1e08dec04 100644 --- a/OpenTween/WebBrowserController.cs +++ b/OpenTween/WebBrowserController.cs @@ -401,7 +401,7 @@ int WebBrowserAPI.IInternetSecurityManager.MapUrlToZone(string pwszUrl, out int return WebBrowserAPI.INET_E_DEFAULT_ACTION; } - const byte URLPOLICY_ALLOW = 0; + private const byte URLPOLICY_ALLOW = 0; int WebBrowserAPI.IInternetSecurityManager.ProcessUrlAction(string pwszUrl, int dwAction, out byte pPolicy, int cbPolicy, byte pContext, int cbContext, int dwFlags, int dwReserved) { From 1c6c6e3fd2c04a0694114f96fa715556785f8708 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 07:23:19 +0900 Subject: [PATCH 104/402] =?UTF-8?q?=E3=82=AA=E3=83=96=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=82=AF=E3=83=88=E5=88=9D=E6=9C=9F=E5=8C=96=E5=AD=90=E3=81=AE?= =?UTF-8?q?=E8=A1=8C=E6=9C=AB=E3=81=AB=E3=82=AB=E3=83=B3=E3=83=9E=E3=82=92?= =?UTF-8?q?=E4=BB=98=E3=81=91=E3=82=8B=20(SA1413)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Connection/OAuthUtilityTest.cs | 12 ++++++++++-- .../Thumbnail/Services/SimpleThumbnailService.cs | 2 +- OpenTween/Tween.cs | 8 +++++--- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/OpenTween.Tests/Connection/OAuthUtilityTest.cs b/OpenTween.Tests/Connection/OAuthUtilityTest.cs index 6717c1fe4..4568fbd2f 100644 --- a/OpenTween.Tests/Connection/OAuthUtilityTest.cs +++ b/OpenTween.Tests/Connection/OAuthUtilityTest.cs @@ -130,8 +130,16 @@ public void CreateAuthorization_Test() .Select(x => x.Split(new[] { '=' }, 2)) .ToDictionary(x => x[0], x => x[1].Substring(1, x[1].Length - 2)); // x[1] は前後の「"」を除去する - var expectAuthzParamKeys = new[] { "realm", "oauth_consumer_key", "oauth_nonce", "oauth_signature_method", - "oauth_timestamp", "oauth_token", "oauth_version", "oauth_signature" }; + var expectAuthzParamKeys = new[] { + "realm", + "oauth_consumer_key", + "oauth_nonce", + "oauth_signature_method", + "oauth_timestamp", + "oauth_token", + "oauth_version", + "oauth_signature", + }; Assert.Equal(expectAuthzParamKeys, parsedParams.Keys, AnyOrderComparer.Instance); Assert.Equal("Realm", parsedParams["realm"]); diff --git a/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs b/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs index 26b4399d2..ca509f110 100644 --- a/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/SimpleThumbnailService.cs @@ -71,7 +71,7 @@ public SimpleThumbnailService(Regex regex, string replacement, string? file_repl MediaPageUrl = url, ThumbnailImageUrl = thumbnailUrl, TooltipText = null, - FullSizeImageUrl = this.ReplaceUrl(url, this.fullsizeReplacement) + FullSizeImageUrl = this.ReplaceUrl(url, this.fullsizeReplacement), }; }, token); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 6a9e446aa..912feacf1 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -679,7 +679,7 @@ private void InitColumns(ListView list, bool startup) SettingManager.Local.DisplayIndex1, SettingManager.Local.DisplayIndex2, SettingManager.Local.DisplayIndex3, SettingManager.Local.DisplayIndex4, SettingManager.Local.DisplayIndex5, SettingManager.Local.DisplayIndex6, - SettingManager.Local.DisplayIndex7, SettingManager.Local.DisplayIndex8 + SettingManager.Local.DisplayIndex7, SettingManager.Local.DisplayIndex8, }; foreach (var i in Enumerable.Range(0, displayIndex.Length)) @@ -4762,7 +4762,8 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) post.ScreenName, "", mk.ToString(), - post.Source }; + post.Source, + }; itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl); } else @@ -4774,7 +4775,8 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) post.ScreenName + Environment.NewLine + "(RT:" + post.RetweetedBy + ")", "", mk.ToString(), - post.Source }; + post.Source, + }; itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl); } itm.StateIndex = post.StateIndex; From 23bee06dc68c18e1b800aff65f217dd051bf4537 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 07:26:59 +0900 Subject: [PATCH 105/402] =?UTF-8?q?ValueTuple=E3=81=AE=E5=90=84=E8=A6=81?= =?UTF-8?q?=E7=B4=A0=E3=81=AB=E5=90=8D=E5=89=8D=E3=82=92=E4=BB=98=E3=81=91?= =?UTF-8?q?=E3=82=8B=20(SA1414)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApiKey.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenTween/ApiKey.cs b/OpenTween/ApiKey.cs index d2018b722..843718151 100644 --- a/OpenTween/ApiKey.cs +++ b/OpenTween/ApiKey.cs @@ -187,7 +187,7 @@ private static byte[] GenerateSalt() return salt; } - private static (byte[], byte[], byte[]) GenerateKeyAndIV(string password, byte[] salt) + private static (byte[] EncryptionKey, byte[] IV, byte[] MacKey) GenerateKeyAndIV(string password, byte[] salt) { using var generator = new Rfc2898DeriveBytes(password, salt, IterationCount, HashAlgorithm); var encryptionKey = generator.GetBytes(KeySize); From a8046d63b61f802c2c2f50b7f587ec8f73e09d58 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 07:28:20 +0900 Subject: [PATCH 106/402] =?UTF-8?q?=E3=83=96=E3=83=AD=E3=83=83=E3=82=AF?= =?UTF-8?q?=E3=81=AE=E6=8B=AC=E5=BC=A7=E3=82=92=E7=8B=AC=E7=AB=8B=E3=81=97?= =?UTF-8?q?=E3=81=9F=E8=A1=8C=E3=81=AB=E6=9B=B8=E3=81=8F=20(SA1500,=20SA15?= =?UTF-8?q?01,=20SA1502)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Api/TwitterApiStatusTest.cs | 21 ++-- OpenTween.Tests/Api/TwitterApiTest.cs | 113 ++++++++++++------ .../Connection/OAuthUtilityTest.cs | 6 +- OpenTween.Tests/MemoryImageTest.cs | 4 +- OpenTween.Tests/OTBaseFormTest.cs | 4 +- OpenTween.Tests/ShortcutCommandTest.cs | 3 +- OpenTween/ApiKey.cs | 19 ++- OpenTween/AppendSettingDialog.cs | 3 +- OpenTween/ApplicationEvents.cs | 4 +- OpenTween/AuthDialog.cs | 4 +- OpenTween/FilterDialog.cs | 5 +- OpenTween/HashtagManage.cs | 9 +- OpenTween/ImageCache.cs | 3 +- OpenTween/ImageListViewItem.cs | 12 +- OpenTween/ListAvailable.cs | 7 +- OpenTween/ListManage.cs | 4 +- OpenTween/MediaItem.cs | 4 +- OpenTween/MediaSelector.cs | 3 +- OpenTween/MemoryImage.cs | 19 ++- OpenTween/MyCommon.cs | 3 +- OpenTween/MyLists.cs | 8 +- OpenTween/OTPictureBox.cs | 24 +++- OpenTween/Setting/SettingBase.cs | 7 +- OpenTween/ShortUrl.cs | 8 +- OpenTween/TabException.cs | 19 ++- .../Thumbnail/Services/ImgAzyobuziNet.cs | 18 ++- .../Services/MetaThumbnailService.cs | 4 +- OpenTween/Thumbnail/Services/Nicovideo.cs | 8 +- OpenTween/Thumbnail/Services/Tinami.cs | 4 +- OpenTween/Thumbnail/Services/Tumblr.cs | 9 +- OpenTween/Thumbnail/Services/Vimeo.cs | 4 +- OpenTween/Tween.cs | 67 +++++++---- OpenTween/Twitter.cs | 10 +- OpenTween/WebApiException.cs | 14 ++- OpenTween/WebBrowserController.cs | 3 +- 35 files changed, 321 insertions(+), 136 deletions(-) diff --git a/OpenTween.Tests/Api/TwitterApiStatusTest.cs b/OpenTween.Tests/Api/TwitterApiStatusTest.cs index a1132e7b1..677238475 100644 --- a/OpenTween.Tests/Api/TwitterApiStatusTest.cs +++ b/OpenTween.Tests/Api/TwitterApiStatusTest.cs @@ -52,7 +52,8 @@ public void ResetTest() public static readonly TheoryData, ApiLimit?> ParseRateLimitTestCase = new TheoryData, ApiLimit?> { { - new Dictionary { + new Dictionary + { ["X-RateLimit-Limit"] = "150", ["X-RateLimit-Remaining"] = "100", ["X-RateLimit-Reset"] = "1356998400", @@ -60,7 +61,8 @@ public void ResetTest() new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)) }, { - new Dictionary(StringComparer.OrdinalIgnoreCase) { + new Dictionary(StringComparer.OrdinalIgnoreCase) + { ["x-ratelimit-limit"] = "150", ["x-ratelimit-remaining"] = "100", ["x-ratelimit-reset"] = "1356998400", @@ -68,7 +70,8 @@ public void ResetTest() new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)) }, { - new Dictionary(StringComparer.OrdinalIgnoreCase) { + new Dictionary(StringComparer.OrdinalIgnoreCase) + { ["X-RateLimit-Limit"] = "150", ["X-RateLimit-Remaining"] = "100", ["X-RateLimit-Reset"] = "hogehoge", @@ -76,7 +79,8 @@ public void ResetTest() null }, { - new Dictionary { + new Dictionary + { ["X-RateLimit-Limit"] = "150", ["X-RateLimit-Remaining"] = "100", }, @@ -95,7 +99,8 @@ public void ParseRateLimitTest(IDictionary header, ApiLimit? exp public static readonly TheoryData, ApiLimit?> ParseMediaRateLimitTestCase = new TheoryData, ApiLimit?> { { - new Dictionary { + new Dictionary + { ["X-MediaRateLimit-Limit"] = "30", ["X-MediaRateLimit-Remaining"] = "20", ["X-MediaRateLimit-Reset"] = "1234567890", @@ -103,7 +108,8 @@ public void ParseRateLimitTest(IDictionary header, ApiLimit? exp new ApiLimit(30, 20, new DateTimeUtc(2009, 2, 13, 23, 31, 30)) }, { - new Dictionary { + new Dictionary + { ["X-MediaRateLimit-Limit"] = "30", ["X-MediaRateLimit-Remaining"] = "20", ["X-MediaRateLimit-Reset"] = "hogehoge", @@ -111,7 +117,8 @@ public void ParseRateLimitTest(IDictionary header, ApiLimit? exp null }, { - new Dictionary { + new Dictionary + { ["X-MediaRateLimit-Limit"] = "30", ["X-MediaRateLimit-Remaining"] = "20", }, diff --git a/OpenTween.Tests/Api/TwitterApiTest.cs b/OpenTween.Tests/Api/TwitterApiTest.cs index 529619660..db9bd0ee7 100644 --- a/OpenTween.Tests/Api/TwitterApiTest.cs +++ b/OpenTween.Tests/Api/TwitterApiTest.cs @@ -88,7 +88,8 @@ public async Task StatusesHomeTimeline_Test() mock.Setup(x => x.GetAsync( new Uri("statuses/home_timeline.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "include_entities", "true" }, { "include_ext_alt_text", "true" }, { "tweet_mode", "extended" }, @@ -116,7 +117,8 @@ public async Task StatusesMentionsTimeline_Test() mock.Setup(x => x.GetAsync( new Uri("statuses/mentions_timeline.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "include_entities", "true" }, { "include_ext_alt_text", "true" }, { "tweet_mode", "extended" }, @@ -144,7 +146,8 @@ public async Task StatusesUserTimeline_Test() mock.Setup(x => x.GetAsync( new Uri("statuses/user_timeline.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "screen_name", "twitterapi" }, { "include_rts", "true" }, { "include_entities", "true" }, @@ -174,7 +177,8 @@ public async Task StatusesShow_Test() mock.Setup(x => x.GetAsync( new Uri("statuses/show.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "id", "100" }, { "include_entities", "true" }, { "include_ext_alt_text", "true" }, @@ -200,7 +204,8 @@ public async Task StatusesUpdate_Test() mock.Setup(x => x.PostLazyAsync( new Uri("statuses/update.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "status", "hogehoge" }, { "include_entities", "true" }, { "include_ext_alt_text", "true" }, @@ -238,11 +243,12 @@ public async Task StatusesUpdate_ExcludeReplyUserIdsEmptyTest() mock.Setup(x => x.PostLazyAsync( new Uri("statuses/update.json", UriKind.Relative), - new Dictionary { - { "status", "hogehoge" }, - { "include_entities", "true" }, - { "include_ext_alt_text", "true" }, - { "tweet_mode", "extended" }, + new Dictionary + { + { "status", "hogehoge" }, + { "include_entities", "true" }, + { "include_ext_alt_text", "true" }, + { "tweet_mode", "extended" }, // exclude_reply_user_ids は空の場合には送信されない }) ) @@ -286,7 +292,8 @@ public async Task StatusesRetweet_Test() mock.Setup(x => x.PostLazyAsync( new Uri("statuses/retweet.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "id", "100" }, { "include_entities", "true" }, { "include_ext_alt_text", "true" }, @@ -312,7 +319,8 @@ public async Task SearchTweets_Test() mock.Setup(x => x.GetAsync( new Uri("search/tweets.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "q", "from:twitterapi" }, { "result_type", "recent" }, { "include_entities", "true" }, @@ -343,7 +351,8 @@ public async Task ListsOwnerships_Test() mock.Setup(x => x.GetAsync( new Uri("lists/ownerships.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "screen_name", "twitterapi" }, { "cursor", "-1" }, { "count", "100" }, @@ -368,7 +377,8 @@ public async Task ListsSubscriptions_Test() mock.Setup(x => x.GetAsync( new Uri("lists/subscriptions.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "screen_name", "twitterapi" }, { "cursor", "-1" }, { "count", "100" }, @@ -393,7 +403,8 @@ public async Task ListsMemberships_Test() mock.Setup(x => x.GetAsync( new Uri("lists/memberships.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "screen_name", "twitterapi" }, { "cursor", "-1" }, { "count", "100" }, @@ -419,7 +430,8 @@ public async Task ListsCreate_Test() mock.Setup(x => x.PostLazyAsync( new Uri("lists/create.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "name", "hogehoge" }, { "description", "aaaa" }, { "mode", "private" }, @@ -444,7 +456,8 @@ public async Task ListsUpdate_Test() mock.Setup(x => x.PostLazyAsync( new Uri("lists/update.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "list_id", "12345" }, { "name", "hogehoge" }, { "description", "aaaa" }, @@ -470,7 +483,8 @@ public async Task ListsDestroy_Test() mock.Setup(x => x.PostLazyAsync( new Uri("lists/destroy.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "list_id", "12345" }, }) ) @@ -493,7 +507,8 @@ public async Task ListsStatuses_Test() mock.Setup(x => x.GetAsync( new Uri("lists/statuses.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "list_id", "12345" }, { "include_entities", "true" }, { "include_ext_alt_text", "true" }, @@ -523,7 +538,8 @@ public async Task ListsMembers_Test() mock.Setup(x => x.GetAsync( new Uri("lists/members.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "list_id", "12345" }, { "include_entities", "true" }, { "include_ext_alt_text", "true" }, @@ -550,7 +566,8 @@ public async Task ListsMembersShow_Test() mock.Setup(x => x.GetAsync( new Uri("lists/members/show.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "list_id", "12345" }, { "screen_name", "twitterapi" }, { "include_entities", "true" }, @@ -577,7 +594,8 @@ public async Task ListsMembersCreate_Test() mock.Setup(x => x.PostLazyAsync( new Uri("lists/members/create.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "list_id", "12345" }, { "screen_name", "twitterapi" }, { "include_entities", "true" }, @@ -604,7 +622,8 @@ public async Task ListsMembersDestroy_Test() mock.Setup(x => x.PostLazyAsync( new Uri("lists/members/destroy.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "list_id", "12345" }, { "screen_name", "twitterapi" }, { "include_entities", "true" }, @@ -631,7 +650,8 @@ public async Task DirectMessagesEventsList_Test() mock.Setup(x => x.GetAsync( new Uri("direct_messages/events/list.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "count", "50" }, { "cursor", "12345abcdefg" }, }, @@ -713,7 +733,8 @@ public async Task UsersShow_Test() mock.Setup(x => x.GetAsync( new Uri("users/show.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "screen_name", "twitterapi" }, { "include_entities", "true" }, { "include_ext_alt_text", "true" }, @@ -739,7 +760,8 @@ public async Task UsersLookup_Test() mock.Setup(x => x.GetAsync( new Uri("users/lookup.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "user_id", "11111,22222" }, { "include_entities", "true" }, { "include_ext_alt_text", "true" }, @@ -765,7 +787,8 @@ public async Task UsersReportSpam_Test() mock.Setup(x => x.PostLazyAsync( new Uri("users/report_spam.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "screen_name", "twitterapi" }, { "tweet_mode", "extended" }, }) @@ -789,7 +812,8 @@ public async Task FavoritesList_Test() mock.Setup(x => x.GetAsync( new Uri("favorites/list.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "include_entities", "true" }, { "include_ext_alt_text", "true" }, { "tweet_mode", "extended" }, @@ -817,7 +841,8 @@ public async Task FavoritesCreate_Test() mock.Setup(x => x.PostLazyAsync( new Uri("favorites/create.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "id", "100" }, { "tweet_mode", "extended" }, }) @@ -841,7 +866,8 @@ public async Task FavoritesDestroy_Test() mock.Setup(x => x.PostLazyAsync( new Uri("favorites/destroy.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "id", "100" }, { "tweet_mode", "extended" }, }) @@ -1012,7 +1038,8 @@ public async Task BlocksCreate_Test() mock.Setup(x => x.PostLazyAsync( new Uri("blocks/create.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "screen_name", "twitterapi" }, { "tweet_mode", "extended" }, }) @@ -1036,7 +1063,8 @@ public async Task BlocksDestroy_Test() mock.Setup(x => x.PostLazyAsync( new Uri("blocks/destroy.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "screen_name", "twitterapi" }, { "tweet_mode", "extended" }, }) @@ -1060,7 +1088,8 @@ public async Task AccountVerifyCredentials_Test() mock.Setup(x => x.GetAsync( new Uri("account/verify_credentials.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "include_entities", "true" }, { "include_ext_alt_text", "true" }, { "tweet_mode", "extended" }, @@ -1092,7 +1121,8 @@ public async Task AccountUpdateProfile_Test() mock.Setup(x => x.PostLazyAsync( new Uri("account/update_profile.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "include_entities", "true" }, { "include_ext_alt_text", "true" }, { "tweet_mode", "extended" }, @@ -1123,7 +1153,8 @@ public async Task AccountUpdateProfileImage_Test() mock.Setup(x => x.PostLazyAsync( new Uri("account/update_profile_image.json", UriKind.Relative), - new Dictionary { + new Dictionary + { { "include_entities", "true" }, { "include_ext_alt_text", "true" }, { "tweet_mode", "extended" }, @@ -1191,7 +1222,8 @@ public async Task MediaUploadInit_Test() mock.Setup(x => x.PostLazyAsync( new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute), - new Dictionary { + new Dictionary + { { "command", "INIT" }, { "total_bytes", "123456" }, { "media_type", "image/png" }, @@ -1219,7 +1251,8 @@ public async Task MediaUploadAppend_Test() mock.Setup(x => x.PostAsync( new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute), - new Dictionary { + new Dictionary + { { "command", "APPEND" }, { "media_id", "11111" }, { "segment_index", "1" }, @@ -1244,7 +1277,8 @@ public async Task MediaUploadFinalize_Test() mock.Setup(x => x.PostLazyAsync( new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute), - new Dictionary { + new Dictionary + { { "command", "FINALIZE" }, { "media_id", "11111" }, }) @@ -1268,7 +1302,8 @@ public async Task MediaUploadStatus_Test() mock.Setup(x => x.GetAsync( new Uri("https://upload.twitter.com/1.1/media/upload.json", UriKind.Absolute), - new Dictionary { + new Dictionary + { { "command", "STATUS" }, { "media_id", "11111" }, }, diff --git a/OpenTween.Tests/Connection/OAuthUtilityTest.cs b/OpenTween.Tests/Connection/OAuthUtilityTest.cs index 4568fbd2f..e87c0a4d5 100644 --- a/OpenTween.Tests/Connection/OAuthUtilityTest.cs +++ b/OpenTween.Tests/Connection/OAuthUtilityTest.cs @@ -77,7 +77,8 @@ public void CreateSignature_NormarizeParametersTest() "TokenSecret", "GET", new Uri("http://example.com/hoge"), - new Dictionary { + new Dictionary + { ["bbb"] = "bar", ["aaa"] = "foo", }); @@ -130,7 +131,8 @@ public void CreateAuthorization_Test() .Select(x => x.Split(new[] { '=' }, 2)) .ToDictionary(x => x[0], x => x[1].Substring(1, x[1].Length - 2)); // x[1] は前後の「"」を除去する - var expectAuthzParamKeys = new[] { + var expectAuthzParamKeys = new[] + { "realm", "oauth_consumer_key", "oauth_nonce", diff --git a/OpenTween.Tests/MemoryImageTest.cs b/OpenTween.Tests/MemoryImageTest.cs index 390d5dca7..2b406f9a7 100644 --- a/OpenTween.Tests/MemoryImageTest.cs +++ b/OpenTween.Tests/MemoryImageTest.cs @@ -62,7 +62,9 @@ public void CopyFromImage_Test() using (var bitmap = new Bitmap(width: 200, height: 200)) { // MemoryImage をエラー無く作成できることをテストする - using (var image = MemoryImage.CopyFromImage(bitmap)) { } + using (var image = MemoryImage.CopyFromImage(bitmap)) + { + } } } diff --git a/OpenTween.Tests/OTBaseFormTest.cs b/OpenTween.Tests/OTBaseFormTest.cs index 5186a26aa..fc27c757c 100644 --- a/OpenTween.Tests/OTBaseFormTest.cs +++ b/OpenTween.Tests/OTBaseFormTest.cs @@ -32,7 +32,9 @@ namespace OpenTween { public class OTBaseFormTest { - private class TestForm : OTBaseForm { } + private class TestForm : OTBaseForm + { + } public OTBaseFormTest() => this.SetupSynchronizationContext(); diff --git a/OpenTween.Tests/ShortcutCommandTest.cs b/OpenTween.Tests/ShortcutCommandTest.cs index 8439a2f1b..f03c565e7 100644 --- a/OpenTween.Tests/ShortcutCommandTest.cs +++ b/OpenTween.Tests/ShortcutCommandTest.cs @@ -150,7 +150,8 @@ public async Task RunCommand_AsyncTest() var invoked = false; var shortcut = ShortcutCommand.Create(Keys.F5) - .Do(async () => { + .Do(async () => + { await Task.Delay(100).ConfigureAwait(false); invoked = true; }); diff --git a/OpenTween/ApiKey.cs b/OpenTween/ApiKey.cs index 843718151..0ed7920ec 100644 --- a/OpenTween/ApiKey.cs +++ b/OpenTween/ApiKey.cs @@ -234,12 +234,23 @@ public static bool TryGetValue(this ValueTuple apiKeys, out Valu [Serializable] public class ApiKeyDecryptException : Exception { - public ApiKeyDecryptException() { } + public ApiKeyDecryptException() + { + } + public ApiKeyDecryptException(string message) - : base(message) { } + : base(message) + { + } + public ApiKeyDecryptException(string message, Exception innerException) - : base(message, innerException) { } + : base(message, innerException) + { + } + protected ApiKeyDecryptException(SerializationInfo info, StreamingContext context) - : base(info, context) { } + : base(info, context) + { + } } } diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index b6afa6181..a510e5c80 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -299,7 +299,8 @@ private void Setting_Shown(object sender, EventArgs e) { Thread.Sleep(10); if (this.Disposing || this.IsDisposed) return; - } while (!this.IsHandleCreated); + } + while (!this.IsHandleCreated); this.TopMost = this.PreviewPanel.CheckAlwaysTop.Checked; this.GetPeriodPanel.LabelPostAndGet.Visible = this.GetPeriodPanel.CheckPostAndGet.Checked; diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 17a41ae47..02d34fa5d 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -276,7 +276,9 @@ public static void InitCulture() { currentCulture = new CultureInfo(settingCultureStr); } - catch (CultureNotFoundException) { } + catch (CultureNotFoundException) + { + } } var preferredCulture = GetPreferredCulture(currentCulture); diff --git a/OpenTween/AuthDialog.cs b/OpenTween/AuthDialog.cs index e3c66a52e..292656f94 100644 --- a/OpenTween/AuthDialog.cs +++ b/OpenTween/AuthDialog.cs @@ -76,7 +76,9 @@ private void MenuItemCopyURL_Click(object sender, EventArgs e) { Clipboard.SetText(this.AuthUrl); } - catch (ExternalException) { } + catch (ExternalException) + { + } } /// diff --git a/OpenTween/FilterDialog.cs b/OpenTween/FilterDialog.cs index d0d98897f..dcdd0a1f1 100644 --- a/OpenTween/FilterDialog.cs +++ b/OpenTween/FilterDialog.cs @@ -987,7 +987,10 @@ private async void ButtonAddTab_Click(object sender, EventArgs e) cancellationToken.ThrowIfCancellationRequested(); } - catch (OperationCanceledException) { return; } + catch (OperationCanceledException) + { + return; + } catch (WebApiException ex) { MessageBox.Show("Failed to get lists. (" + ex.Message + ")"); diff --git a/OpenTween/HashtagManage.cs b/OpenTween/HashtagManage.cs index f09032cf9..f3ee11551 100644 --- a/OpenTween/HashtagManage.cs +++ b/OpenTween/HashtagManage.cs @@ -120,7 +120,8 @@ private void UnSelectButton_Click(object sender, EventArgs e) do { this.HistoryHashList.SelectedIndices.Clear(); - } while (this.HistoryHashList.SelectedIndices.Count > 0); + } + while (this.HistoryHashList.SelectedIndices.Count > 0); } private int GetIndexOf(ListBox.ObjectCollection list, string value) @@ -305,7 +306,8 @@ private void PermOK_Button_Click(object sender, EventArgs e) do { this.HistoryHashList.SelectedIndices.Clear(); - } while (this.HistoryHashList.SelectedIndices.Count > 0); + } + while (this.HistoryHashList.SelectedIndices.Count > 0); this.HistoryHashList.Items.Insert(idx, hashStr); this.HistoryHashList.SelectedIndex = idx; } @@ -315,7 +317,8 @@ private void PermOK_Button_Click(object sender, EventArgs e) do { this.HistoryHashList.SelectedIndices.Clear(); - } while (this.HistoryHashList.SelectedIndices.Count > 0); + } + while (this.HistoryHashList.SelectedIndices.Count > 0); this.HistoryHashList.SelectedIndex = this.HistoryHashList.Items.IndexOf(hashStr); } diff --git a/OpenTween/ImageCache.cs b/OpenTween/ImageCache.cs index 738a7297d..1789ffbf5 100644 --- a/OpenTween/ImageCache.cs +++ b/OpenTween/ImageCache.cs @@ -59,7 +59,8 @@ public class ImageCache : IDisposable public ImageCache() { this.InnerDictionary = new LRUCacheDictionary>(trimLimit: 300, autoTrimCount: 100); - this.InnerDictionary.CacheRemoved += (s, e) => { + this.InnerDictionary.CacheRemoved += (s, e) => + { // まだ参照されている場合もあるのでDisposeはファイナライザ任せ this.CacheRemoveCount++; }; diff --git a/OpenTween/ImageListViewItem.cs b/OpenTween/ImageListViewItem.cs index 65cfe65f2..9d8c41d4c 100644 --- a/OpenTween/ImageListViewItem.cs +++ b/OpenTween/ImageListViewItem.cs @@ -110,9 +110,15 @@ private async Task GetImageAsyncInternal(bool force) this.ImageDownloaded?.Invoke(this, EventArgs.Empty); } } - catch (HttpRequestException) { } - catch (InvalidImageException) { } - catch (TaskCanceledException) { } + catch (HttpRequestException) + { + } + catch (InvalidImageException) + { + } + catch (TaskCanceledException) + { + } } public MemoryImage Image diff --git a/OpenTween/ListAvailable.cs b/OpenTween/ListAvailable.cs index c4e236001..0a88f0547 100644 --- a/OpenTween/ListAvailable.cs +++ b/OpenTween/ListAvailable.cs @@ -47,7 +47,8 @@ public ListAvailable() private void OK_Button_Click(object sender, EventArgs e) { - if (this.ListsList.SelectedIndex > -1) { + if (this.ListsList.SelectedIndex > -1) + { this.SelectedList = (ListElement)this.ListsList.SelectedItem; this.DialogResult = System.Windows.Forms.DialogResult.OK; this.Close(); @@ -133,7 +134,9 @@ private async void RefreshButton_Click(object sender, EventArgs e) var lists = await this.FetchListsAsync(); this.UpdateListsListBox(lists); } - catch (OperationCanceledException) { } + catch (OperationCanceledException) + { + } catch (WebApiException ex) { MessageBox.Show("Failed to get lists. (" + ex.Message + ")"); diff --git a/OpenTween/ListManage.cs b/OpenTween/ListManage.cs index ef81c177d..02807e969 100644 --- a/OpenTween/ListManage.cs +++ b/OpenTween/ListManage.cs @@ -373,7 +373,9 @@ private async void RefreshListsButton_Click(object sender, EventArgs e) var lists = await this.FetchListsAsync(); this.UpdateListsListBox(lists); } - catch (OperationCanceledException) { } + catch (OperationCanceledException) + { + } catch (WebApiException ex) { MessageBox.Show(string.Format(Properties.Resources.ListsDeleteFailed, ex.Message)); diff --git a/OpenTween/MediaItem.cs b/OpenTween/MediaItem.cs index 122b305a0..a2e7dbbc8 100644 --- a/OpenTween/MediaItem.cs +++ b/OpenTween/MediaItem.cs @@ -128,7 +128,9 @@ public bool IsImage try { // MemoryImage が生成できるかを検証する - using (var image = this.CreateImage()) { } + using (var image = this.CreateImage()) + { + } this.isImage = true; } diff --git a/OpenTween/MediaSelector.cs b/OpenTween/MediaSelector.cs index bd8592796..f24b52c34 100644 --- a/OpenTween/MediaSelector.cs +++ b/OpenTween/MediaSelector.cs @@ -136,7 +136,8 @@ private void CreateServices(Twitter tw, TwitterConfiguration twitterConfig) { this.pictureService?.Clear(); - this.pictureService = new Dictionary { + this.pictureService = new Dictionary + { ["Twitter"] = new TwitterPhoto(tw, twitterConfig), ["Imgur"] = new Imgur(twitterConfig), ["Mobypicture"] = new Mobypicture(tw, twitterConfig), diff --git a/OpenTween/MemoryImage.cs b/OpenTween/MemoryImage.cs index 2103c3a15..cc1150b0f 100644 --- a/OpenTween/MemoryImage.cs +++ b/OpenTween/MemoryImage.cs @@ -351,12 +351,23 @@ public static MemoryImage CopyFromImage(Image image) [Serializable] public class InvalidImageException : Exception { - public InvalidImageException() { } + public InvalidImageException() + { + } + public InvalidImageException(string message) - : base(message) { } + : base(message) + { + } + public InvalidImageException(string message, Exception innerException) - : base(message, innerException) { } + : base(message, innerException) + { + } + protected InvalidImageException(SerializationInfo info, StreamingContext context) - : base(info, context) { } + : base(info, context) + { + } } } diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 83b053f65..7e6de3be4 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -689,7 +689,8 @@ public static bool IsAnimatedGif(string filename) public static DateTimeUtc DateTimeParse(string input) { - var formats = new[] { + var formats = new[] + { "ddd MMM dd HH:mm:ss zzzz yyyy", "ddd, d MMM yyyy HH:mm:ss zzzz", }; diff --git a/OpenTween/MyLists.cs b/OpenTween/MyLists.cs index 3f3ebffcd..80fba4739 100644 --- a/OpenTween/MyLists.cs +++ b/OpenTween/MyLists.cs @@ -228,7 +228,9 @@ private async void MenuItemReload_Click(object sender, EventArgs e) { await this.RefreshListBox(); } - catch (OperationCanceledException) { } + catch (OperationCanceledException) + { + } catch (WebApiException ex) { MessageBox.Show($"Failed to get lists. ({ex.Message})"); @@ -244,7 +246,9 @@ private async void ListRefreshButton_Click(object sender, EventArgs e) { await this.RefreshListBox(); } - catch (OperationCanceledException) { } + catch (OperationCanceledException) + { + } catch (WebApiException ex) { MessageBox.Show($"Failed to get lists. ({ex.Message})"); diff --git a/OpenTween/OTPictureBox.cs b/OpenTween/OTPictureBox.cs index d2754bef8..ca5b2c7b4 100644 --- a/OpenTween/OTPictureBox.cs +++ b/OpenTween/OTPictureBox.cs @@ -123,12 +123,24 @@ public async Task SetImageFromTask(Func> imageTask) { throw; } - catch (HttpRequestException) { } - catch (InvalidImageException) { } - catch (OperationCanceledException) { } - catch (ObjectDisposedException) { } - catch (WebException) { } - catch (IOException) { } + catch (HttpRequestException) + { + } + catch (InvalidImageException) + { + } + catch (OperationCanceledException) + { + } + catch (ObjectDisposedException) + { + } + catch (WebException) + { + } + catch (IOException) + { + } } } diff --git a/OpenTween/Setting/SettingBase.cs b/OpenTween/Setting/SettingBase.cs index f9cf25f6b..b46b61824 100644 --- a/OpenTween/Setting/SettingBase.cs +++ b/OpenTween/Setting/SettingBase.cs @@ -154,14 +154,17 @@ protected static void SaveSettings(T instance, string fileId) if (File.Exists(tmpfilePath)) File.Delete(tmpfilePath); } - catch (Exception) { } + catch (Exception) + { + } } // リトライ retryCount++; Thread.Sleep(1000); - } while (retryCount <= SaveRetryMax); + } + while (retryCount <= SaveRetryMax); // リトライオーバー if (lastException != null) diff --git a/OpenTween/ShortUrl.cs b/OpenTween/ShortUrl.cs index ec9a56ba5..896fc7006 100644 --- a/OpenTween/ShortUrl.cs +++ b/OpenTween/ShortUrl.cs @@ -216,8 +216,12 @@ public async Task ExpandUrlAsync(Uri uri, int redirectLimit) expanded = await this.GetRedirectTo(uri) .ConfigureAwait(false); } - catch (TaskCanceledException) { } - catch (HttpRequestException) { } + catch (TaskCanceledException) + { + } + catch (HttpRequestException) + { + } if (expanded == null || expanded == uri) return uri; diff --git a/OpenTween/TabException.cs b/OpenTween/TabException.cs index 0e8a3df3a..b40fcc6c6 100644 --- a/OpenTween/TabException.cs +++ b/OpenTween/TabException.cs @@ -35,12 +35,23 @@ namespace OpenTween [Serializable] public class TabException : Exception { - public TabException() { } + public TabException() + { + } + public TabException(string message) - : base(message) { } + : base(message) + { + } + public TabException(string message, Exception innerException) - : base(message, innerException) { } + : base(message, innerException) + { + } + protected TabException(SerializationInfo info, StreamingContext context) - : base(info, context) { } + : base(info, context) + { + } } } diff --git a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs index bc47e9d8e..766244561 100644 --- a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs +++ b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs @@ -38,7 +38,8 @@ namespace OpenTween.Thumbnail.Services { public class ImgAzyobuziNet : IThumbnailService, IDisposable { - protected string[] apiHosts = { + protected string[] apiHosts = + { "https://img.azyobuzi.net/api/", "https://img.opentween.org/api/", }; @@ -166,9 +167,18 @@ public async Task LoadRegexAsync(string apiBase) return true; } - catch (HttpRequestException) { } // サーバーが2xx以外のステータスコードを返した場合 - catch (OperationCanceledException) { } // リクエストがタイムアウトした場合 - catch (XmlException) { } // サーバーが不正なJSONを返した場合 + catch (HttpRequestException) + { + // サーバーが2xx以外のステータスコードを返した場合 + } + catch (OperationCanceledException) + { + // リクエストがタイムアウトした場合 + } + catch (XmlException) + { + // サーバーが不正なJSONを返した場合 + } return false; } diff --git a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs index 88646ab36..387f40a27 100644 --- a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs @@ -97,7 +97,9 @@ public MetaThumbnailService(HttpClient? http, string urlPattern, string[]? propN TooltipText = null, }; } - catch (HttpRequestException) { } + catch (HttpRequestException) + { + } return null; } diff --git a/OpenTween/Thumbnail/Services/Nicovideo.cs b/OpenTween/Thumbnail/Services/Nicovideo.cs index 7ea67c891..a31b2aaa7 100644 --- a/OpenTween/Thumbnail/Services/Nicovideo.cs +++ b/OpenTween/Thumbnail/Services/Nicovideo.cs @@ -80,8 +80,12 @@ public class Nicovideo : IThumbnailService IsPlayable = true, }; } - catch (XmlException) { } - catch (HttpRequestException) { } + catch (XmlException) + { + } + catch (HttpRequestException) + { + } return null; } diff --git a/OpenTween/Thumbnail/Services/Tinami.cs b/OpenTween/Thumbnail/Services/Tinami.cs index b6a502c3c..695fed7a1 100644 --- a/OpenTween/Thumbnail/Services/Tinami.cs +++ b/OpenTween/Thumbnail/Services/Tinami.cs @@ -91,7 +91,9 @@ public Tinami(ApiKey apiKey, HttpClient? http) TooltipText = descElm?.Value, }; } - catch (HttpRequestException) { } + catch (HttpRequestException) + { + } return null; } diff --git a/OpenTween/Thumbnail/Services/Tumblr.cs b/OpenTween/Thumbnail/Services/Tumblr.cs index 8de69086a..b29895955 100644 --- a/OpenTween/Thumbnail/Services/Tumblr.cs +++ b/OpenTween/Thumbnail/Services/Tumblr.cs @@ -93,8 +93,13 @@ public Tumblr(ApiKey apiKey, HttpClient? http) return thumbs.FirstOrDefault(); } - catch (XmlException) { } - catch (HttpRequestException) { } // たまに api.tumblr.com が名前解決できない + catch (XmlException) + { + } + catch (HttpRequestException) + { + // たまに api.tumblr.com が名前解決できない + } return null; } diff --git a/OpenTween/Thumbnail/Services/Vimeo.cs b/OpenTween/Thumbnail/Services/Vimeo.cs index 991b7d07e..674196d94 100644 --- a/OpenTween/Thumbnail/Services/Vimeo.cs +++ b/OpenTween/Thumbnail/Services/Vimeo.cs @@ -96,7 +96,9 @@ public Vimeo(HttpClient? http) IsPlayable = true, }; } - catch (HttpRequestException) { } + catch (HttpRequestException) + { + } return null; } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 912feacf1..06f91b893 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -569,7 +569,8 @@ private void LoadIcons() if (iconRefresh1 == null) { - this.nIconRefresh = new[] { + this.nIconRefresh = new[] + { Properties.Resources.Refresh, Properties.Resources.Refresh2, Properties.Resources.Refresh3, Properties.Resources.Refresh4, }; @@ -675,7 +676,8 @@ private void InitColumns(ListView list, bool startup) columns[6].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width7); columns[7].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width8); - var displayIndex = new[] { + var displayIndex = new[] + { SettingManager.Local.DisplayIndex1, SettingManager.Local.DisplayIndex2, SettingManager.Local.DisplayIndex3, SettingManager.Local.DisplayIndex4, SettingManager.Local.DisplayIndex5, SettingManager.Local.DisplayIndex6, @@ -4755,27 +4757,31 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) ImageListViewItem itm; if (post.RetweetedId == null) { - string[] sitem = { "", - post.Nickname, - post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), - post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), - post.ScreenName, - "", - mk.ToString(), - post.Source, + string[] sitem = + { + "", + post.Nickname, + post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), + post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), + post.ScreenName, + "", + mk.ToString(), + post.Source, }; itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl); } else { - string[] sitem = { "", - post.Nickname, - post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), - post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), - post.ScreenName + Environment.NewLine + "(RT:" + post.RetweetedBy + ")", - "", - mk.ToString(), - post.Source, + string[] sitem = + { + "", + post.Nickname, + post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), + post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), + post.ScreenName + Environment.NewLine + "(RT:" + post.RetweetedBy + ")", + "", + mk.ToString(), + post.Source, }; itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl); } @@ -5571,7 +5577,9 @@ async Task DelayedTasks() { await Task.WhenAll(loadTasks); } - catch (OperationCanceledException) { } + catch (OperationCanceledException) + { + } } // サムネイルの読み込みを待たずに次に選択されたツイートを表示するため await しない @@ -5750,7 +5758,8 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Escape) .FocusedOn(FocusedControl.ListTab) - .Do(() => { + .Do(() => + { this.anchorFlag = false; var tab = this.CurrentTab; var tabtype = tab.TabType; @@ -5899,7 +5908,8 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Control | Keys.PageUp, Keys.Control | Keys.P) .FocusedOn(FocusedControl.StatusText) - .Do(() => { + .Do(() => + { if (this.ListTab.SelectedIndex == 0) { this.ListTab.SelectedIndex = this.ListTab.TabCount - 1; @@ -5913,7 +5923,8 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Control | Keys.PageDown, Keys.Control | Keys.N) .FocusedOn(FocusedControl.StatusText) - .Do(() => { + .Do(() => + { if (this.ListTab.SelectedIndex == this.ListTab.TabCount - 1) { this.ListTab.SelectedIndex = 0; @@ -5927,7 +5938,8 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Control | Keys.Y) .FocusedOn(FocusedControl.PostBrowser) - .Do(() => { + .Do(() => + { var multiline = !SettingManager.Local.StatusMultiline; SettingManager.Local.StatusMultiline = multiline; this.MultiLineMenuItem.Checked = multiline; @@ -6047,7 +6059,8 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.Up) .FocusedOn(FocusedControl.StatusText) - .Do(() => { + .Do(() => + { var tab = this.CurrentTab; var selectedIndex = tab.SelectedIndex; if (selectedIndex != -1 && selectedIndex > 0) @@ -6061,7 +6074,8 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.Down) .FocusedOn(FocusedControl.StatusText) - .Do(() => { + .Do(() => + { var tab = this.CurrentTab; var selectedIndex = tab.SelectedIndex; if (selectedIndex != -1 && selectedIndex < tab.AllCount - 1) @@ -6075,7 +6089,8 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.Space) .FocusedOn(FocusedControl.StatusText) - .Do(() => { + .Do(() => + { if (this.StatusText.SelectionStart > 0) { var endidx = this.StatusText.SelectionStart - 1; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 853ad4889..365cb4ff4 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1241,7 +1241,9 @@ private void CreateDirectMessagesEventFromJson( { post.SourceUri = new Uri(SourceUriBase, app.Url); } - catch (UriFormatException) { } + catch (UriFormatException) + { + } } post.IsRead = read; @@ -1375,7 +1377,8 @@ public async Task RefreshFollowerIds() newFollowerIds = newFollowerIds.Concat(ret.Ids); cursor = ret.NextCursor; - } while (cursor != 0); + } + while (cursor != 0); this.followerId = newFollowerIds.ToHashSet(); TabInformations.GetInstance().RefreshOwl(this.followerId); @@ -1623,7 +1626,8 @@ public async Task RefreshBlockIds() newBlockIds = newBlockIds.Concat(ret.Ids); cursor = ret.NextCursor; - } while (cursor != 0); + } + while (cursor != 0); var blockIdsSet = newBlockIds.ToHashSet(); blockIdsSet.Remove(this.UserId); // 元のソースにあったので一応残しておく diff --git a/OpenTween/WebApiException.cs b/OpenTween/WebApiException.cs index a3bb1bed0..75eac8385 100644 --- a/OpenTween/WebApiException.cs +++ b/OpenTween/WebApiException.cs @@ -37,11 +37,19 @@ public class WebApiException : Exception { public string? ResponseText { get; } = null; - public WebApiException() { } + public WebApiException() + { + } + public WebApiException(string message) - : base(message) { } + : base(message) + { + } + public WebApiException(string message, Exception innerException) - : base(message, innerException) { } + : base(message, innerException) + { + } public WebApiException(string message, string responseText) : this(message) diff --git a/OpenTween/WebBrowserController.cs b/OpenTween/WebBrowserController.cs index 1e08dec04..2e25b73c3 100644 --- a/OpenTween/WebBrowserController.cs +++ b/OpenTween/WebBrowserController.cs @@ -300,7 +300,8 @@ public InternetSecurityManager(WebBrowser webBrowser) { Thread.Sleep(100); Application.DoEvents(); - } while (webBrowser.ReadyState != WebBrowserReadyState.Complete); + } + while (webBrowser.ReadyState != WebBrowserReadyState.Complete); this.ocx = webBrowser.ActiveXInstance; From 3c0dc2344fd7c21940aaa1880415e1dc4ee82024 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 07:43:06 +0900 Subject: [PATCH 107/402] =?UTF-8?q?=E4=BD=99=E5=88=86=E3=81=AA=E7=A9=BA?= =?UTF-8?q?=E8=A1=8C=E3=82=92=E5=89=8A=E9=99=A4=20(SA1505,=20SA1507,=20SA1?= =?UTF-8?q?508,=20SA1509)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 1 - OpenTween/Growl.cs | 2 -- OpenTween/Models/FilterTabModel.cs | 1 - OpenTween/Models/PostClass.cs | 1 - OpenTween/Models/PostFilterRule.cs | 1 - OpenTween/NativeMethods.cs | 1 - OpenTween/Setting/SettingBase.cs | 1 - OpenTween/Tween.cs | 7 ------- OpenTween/WebBrowserController.cs | 7 ------- 9 files changed, 22 deletions(-) diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 02d34fa5d..1b4e1c9a5 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -81,7 +81,6 @@ public static int Main(string[] args) SettingManager.LoadAll(); InitCulture(); - { // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する var pt = MyCommon.SettingPath.Replace("\\", "/") + "/" + ApplicationSettings.AssemblyName; diff --git a/OpenTween/Growl.cs b/OpenTween/Growl.cs index e4f0b45d7..efc5e5033 100644 --- a/OpenTween/Growl.cs +++ b/OpenTween/Growl.cs @@ -175,7 +175,6 @@ public bool RegisterGrowl() this.growlApp = this.connector.CreateInstance( "Growl.Connector.Application", false, BindingFlags.Default, null, new object[] { this.AppName }, null, null); - if (File.Exists(Path.Combine(Application.StartupPath, "Icons\\Tween.png"))) { // Icons\Tween.pngを使用 @@ -188,7 +187,6 @@ public bool RegisterGrowl() var data = ci.Invoke(new object[] { Path.Combine(Application.StartupPath, "Icons\\Tween.png") }); var pi = this.growlApp.GetType().GetProperty("Icon"); pi.SetValue(this.growlApp, data, null); - } else if (File.Exists(Path.Combine(Application.StartupPath, "Icons\\MIcon.ico"))) { diff --git a/OpenTween/Models/FilterTabModel.cs b/OpenTween/Models/FilterTabModel.cs index be492a5d2..dd27e642c 100644 --- a/OpenTween/Models/FilterTabModel.cs +++ b/OpenTween/Models/FilterTabModel.cs @@ -107,7 +107,6 @@ public MyCommon.HITRESULT AddFiltered(PostClass post, bool immediately = false) return rslt; // マーク付けは呼び出し元で行うこと } - public PostFilterRule[] GetFilters() { lock (this.lockObjFilters) diff --git a/OpenTween/Models/PostClass.cs b/OpenTween/Models/PostClass.cs index e0e3bc02b..add6c52cb 100644 --- a/OpenTween/Models/PostClass.cs +++ b/OpenTween/Models/PostClass.cs @@ -474,7 +474,6 @@ public bool Equals(PostClass? other) (this.RetweetedId == other.RetweetedId) && (this.IsDeleted == other.IsDeleted) && (this.InReplyToUserId == other.InReplyToUserId); - } public override int GetHashCode() diff --git a/OpenTween/Models/PostFilterRule.cs b/OpenTween/Models/PostFilterRule.cs index 069e46f14..ead86ae22 100644 --- a/OpenTween/Models/PostFilterRule.cs +++ b/OpenTween/Models/PostFilterRule.cs @@ -472,7 +472,6 @@ protected Expression MakeGenericFilter( typeof(string).GetMethod("Equals", new[] { typeof(string), typeof(StringComparison) }), targetValue, Expression.Constant(compOpt)); - } else { diff --git a/OpenTween/NativeMethods.cs b/OpenTween/NativeMethods.cs index f3b2986dd..39025566a 100644 --- a/OpenTween/NativeMethods.cs +++ b/OpenTween/NativeMethods.cs @@ -180,7 +180,6 @@ public enum FlashSpecification : uint private static extern bool FlashWindowEx( ref FLASHWINFO FWInfo); - private struct FLASHWINFO { public int cbSize; // FLASHWINFO構造体のサイズ diff --git a/OpenTween/Setting/SettingBase.cs b/OpenTween/Setting/SettingBase.cs index b46b61824..29bb247ef 100644 --- a/OpenTween/Setting/SettingBase.cs +++ b/OpenTween/Setting/SettingBase.cs @@ -162,7 +162,6 @@ protected static void SaveSettings(T instance, string fileId) // リトライ retryCount++; Thread.Sleep(1000); - } while (retryCount <= SaveRetryMax); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 06f91b893..15f5e2eb5 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1480,7 +1480,6 @@ private void RefreshTimeline() if (!this.StatusLabelUrl.Text.StartsWith("http", StringComparison.Ordinal)) this.SetStatusLabelUrl(); this.HashSupl.AddRangeItem(this.tw.GetHashList()); - } internal struct ListViewScroll @@ -1806,7 +1805,6 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo break; } sb.Append(post.TextFromApi); - } var title = new StringBuilder(); @@ -2926,7 +2924,6 @@ private async void FavAddToolStripMenuItem_Click(object sender, EventArgs e) private async void FavRemoveToolStripMenuItem_Click(object sender, EventArgs e) => await this.FavoriteChange(false); - private async void FavoriteRetweetMenuItem_Click(object sender, EventArgs e) => await this.FavoritesRetweetOfficial(); @@ -3854,7 +3851,6 @@ private async Task ShowUserTimeline() await this.AddNewTabForUserTimeline(post.ScreenName); } - private async Task ShowRetweeterTimeline() { var retweetedBy = this.CurrentPost?.RetweetedBy; @@ -3862,7 +3858,6 @@ private async Task ShowRetweeterTimeline() await this.AddNewTabForUserTimeline(retweetedBy); } - private void SearchComboBox_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) @@ -8048,7 +8043,6 @@ protected override bool ProcessDialogKey(Keys keyData) { if ((keyData & Keys.Control) == Keys.Control) post = true; } - } else if (SettingManager.Common.PostShiftEnter) // SHift+Enter投稿時 { @@ -8062,7 +8056,6 @@ protected override bool ProcessDialogKey(Keys keyData) { if ((keyData & Keys.Shift) == Keys.Shift) post = true; } - } else // Enter投稿時 { diff --git a/OpenTween/WebBrowserController.cs b/OpenTween/WebBrowserController.cs index 2e25b73c3..bbe35ea1a 100644 --- a/OpenTween/WebBrowserController.cs +++ b/OpenTween/WebBrowserController.cs @@ -118,7 +118,6 @@ public enum URLZONE public static int URLPOLICY_AUTHENTICATE_CHALLENGE_RESPONSE = 0x10000; public static int URLPOLICY_AUTHENTICATE_MUTUAL_ONLY = 0x30000; - public static int URLACTION_COOKIES = 0x1A02; public static int URLACTION_COOKIES_SESSION = 0x1A03; @@ -132,7 +131,6 @@ public enum URLZONE public static int URLACTION_NETWORK_CURR_MAX = 0x1A10; public static int URLACTION_NETWORK_MAX = 0x1BFF; - public static int URLACTION_JAVA_MIN = 0x1C00; public static int URLACTION_JAVA_PERMISSIONS = 0x1C00; public static int URLPOLICY_JAVA_PROHIBIT = 0x0; @@ -143,7 +141,6 @@ public enum URLZONE public static int URLACTION_JAVA_CURR_MAX = 0x1C00; public static int URLACTION_JAVA_MAX = 0x1CFF; - // The following Infodelivery actions should have no default policies // in the registry. They assume that no default policy means fall // back to the global restriction. If an admin sets a policy per @@ -190,10 +187,8 @@ public enum URLZONE public static int URLPOLICY_MASK_PERMISSIONS = 0xF; - public static int URLPOLICY_DONTCHECKDLGBOX = 0x100; - // ---------------------------------------------------------------------- // ここ以下は COM Interface の宣言です。 public static Guid IID_IProfferService = new Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0"); @@ -326,7 +321,6 @@ public InternetSecurityManager(WebBrowser webBrowser) return; } - this.profferService = (WebBrowserAPI.IProfferService)Marshal.GetObjectForIUnknown(this.profferServicePtr); // IProfferService.ProfferService() を使って @@ -353,7 +347,6 @@ int WebBrowserAPI.IServiceProvider.QueryService( ref Guid riid, out IntPtr ppvObject) { - ppvObject = IntPtr.Zero; if (guidService.CompareTo( WebBrowserAPI.IID_IInternetSecurityManager) == 0) From 1c72e21788978108029d5e081cdfe0c82670cae5 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 08:09:31 +0900 Subject: [PATCH 108/402] =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89?= =?UTF-8?q?=E3=83=BB=E3=83=97=E3=83=AD=E3=83=91=E3=83=86=E3=82=A3=E3=81=AE?= =?UTF-8?q?=E5=89=8D=E5=BE=8C=E3=81=AB=E7=A9=BA=E8=A1=8C=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=20(SA1516)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Connection/LazyJsonTest.cs | 4 +++ OpenTween.Tests/MockTimer.cs | 2 ++ OpenTween.Tests/Models/PostClassTest.cs | 4 +++ ...PostFilterRuleVersion113DeserializeTest.cs | 19 +++++++++++ OpenTween.Tests/MyCommonTest.cs | 1 + OpenTween/Api/BitlyApi.cs | 2 ++ .../Api/DataModel/TwitterUploadMediaResult.cs | 1 + OpenTween/Api/MicrosoftTranslatorApi.cs | 2 ++ OpenTween/Api/TwitterApi.cs | 1 + OpenTween/Api/TwitterApiException.cs | 1 + OpenTween/Api/TwitterApiStatus.cs | 3 ++ OpenTween/AsyncTimer.cs | 1 + OpenTween/AtIdSupplement.cs | 1 + OpenTween/Connection/Networking.cs | 1 + OpenTween/Connection/OAuthEchoHandler.cs | 1 + OpenTween/Connection/OAuthHandler.cs | 3 ++ OpenTween/Connection/TwitterApiConnection.cs | 1 + OpenTween/DebounceTimer.cs | 2 ++ OpenTween/DetailsListView.cs | 1 + OpenTween/FilterDialog.cs | 1 + OpenTween/Growl.cs | 2 ++ OpenTween/HashtagManage.cs | 3 ++ OpenTween/HookGlobalHotkey.cs | 2 ++ OpenTween/InputTabName.cs | 1 + OpenTween/LRUCacheDictionary.cs | 2 ++ OpenTween/LoginDialog.cs | 2 ++ OpenTween/MediaItem.cs | 3 ++ OpenTween/MediaSelector.cs | 4 +++ OpenTween/Models/FilterTabModel.cs | 1 + OpenTween/Models/MediaInfo.cs | 2 ++ OpenTween/Models/PostClass.cs | 33 +++++++++++++++++++ OpenTween/Models/PostFilterRule.cs | 21 ++++++++++++ OpenTween/Models/TabInformations.cs | 1 + OpenTween/Models/TabModel.cs | 9 +++++ OpenTween/MouseWheelMessageFilter.cs | 1 + OpenTween/MyCommon.cs | 3 ++ OpenTween/NativeMethods.cs | 5 +++ OpenTween/OTPictureBox.cs | 1 + OpenTween/OTSplitContainer.cs | 3 ++ OpenTween/OpenURL.cs | 1 + OpenTween/PostStatusParams.cs | 5 +++ OpenTween/SearchWordDialog.cs | 5 +++ OpenTween/SendErrorReportForm.cs | 5 +++ OpenTween/Setting/SettingCommon.cs | 6 ++++ OpenTween/Setting/SettingLocal.cs | 23 +++++++++++++ OpenTween/ShortUrl.cs | 2 ++ OpenTween/TabsDialog.cs | 2 ++ OpenTween/Thumbnail/MapThumb.cs | 1 + .../Thumbnail/Services/ImgAzyobuziNet.cs | 1 + .../Services/MetaThumbnailService.cs | 1 + OpenTween/TimelineScheduler.cs | 1 + OpenTween/ToolStripAPIGauge.cs | 3 ++ OpenTween/ToolStripLabelHistory.cs | 3 ++ OpenTween/Tween.cs | 18 ++++++++-- OpenTween/TweetThumbnail.cs | 2 ++ OpenTween/Twitter.cs | 11 +++++++ OpenTween/UserInfo.cs | 1 + 57 files changed, 240 insertions(+), 2 deletions(-) diff --git a/OpenTween.Tests/Connection/LazyJsonTest.cs b/OpenTween.Tests/Connection/LazyJsonTest.cs index 862b83dda..0c003aca9 100644 --- a/OpenTween.Tests/Connection/LazyJsonTest.cs +++ b/OpenTween.Tests/Connection/LazyJsonTest.cs @@ -97,9 +97,13 @@ private class InvalidStream : Stream public bool IsDisposed { get; private set; } = false; public override bool CanRead => true; + public override bool CanSeek => false; + public override bool CanWrite => false; + public override long Length => 100L; + public override long Position { get => 0L; diff --git a/OpenTween.Tests/MockTimer.cs b/OpenTween.Tests/MockTimer.cs index 6be4ac5ad..ed537e1c7 100644 --- a/OpenTween.Tests/MockTimer.cs +++ b/OpenTween.Tests/MockTimer.cs @@ -31,7 +31,9 @@ namespace OpenTween public class MockTimer : ITimer { public bool IsTimerRunning { get; private set; } = false; + public TimeSpan DueTime { get; private set; } = Timeout.InfiniteTimeSpan; + public TimeSpan Period { get; private set; } = Timeout.InfiniteTimeSpan; private readonly Func callback; diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index 6d3b38aa7..c385806f8 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -35,6 +35,7 @@ public class PostClassTest private class PostClassGroup { private Dictionary testCases; + public PostClassGroup(params TestPostClass[] postClasses) { this.testCases = new Dictionary(); @@ -44,11 +45,14 @@ public PostClassGroup(params TestPostClass[] postClasses) this.testCases.Add(p.StatusId, p); } } + public PostClass this[long id] => this.testCases[id]; } + private class TestPostClass : PostClass { public PostClassGroup? Group; + protected override PostClass RetweetSource { get diff --git a/OpenTween.Tests/Models/PostFilterRuleVersion113DeserializeTest.cs b/OpenTween.Tests/Models/PostFilterRuleVersion113DeserializeTest.cs index 52f09cb53..ac928f126 100644 --- a/OpenTween.Tests/Models/PostFilterRuleVersion113DeserializeTest.cs +++ b/OpenTween.Tests/Models/PostFilterRuleVersion113DeserializeTest.cs @@ -40,24 +40,43 @@ public class PostFilterRuleVersion113DeserializeTest public sealed class FiltersClass { public string? NameFilter { get; set; } + public string? ExNameFilter { get; set; } + public string[] BodyFilterArray { get; set; } = Array.Empty(); + public string[] ExBodyFilterArray { get; set; } = Array.Empty(); + public bool SearchBoth { get; set; } + public bool ExSearchBoth { get; set; } + public bool MoveFrom { get; set; } + public bool SetMark { get; set; } + public bool SearchUrl { get; set; } + public bool ExSearchUrl { get; set; } + public bool CaseSensitive { get; set; } + public bool ExCaseSensitive { get; set; } + public bool UseLambda { get; set; } + public bool ExUseLambda { get; set; } + public bool UseRegex { get; set; } + public bool ExUseRegex { get; set; } + public bool IsRt { get; set; } + public bool IsExRt { get; set; } + public string? Source { get; set; } + public string? ExSource { get; set; } } diff --git a/OpenTween.Tests/MyCommonTest.cs b/OpenTween.Tests/MyCommonTest.cs index 497aab04d..6c50d95c9 100644 --- a/OpenTween.Tests/MyCommonTest.cs +++ b/OpenTween.Tests/MyCommonTest.cs @@ -124,6 +124,7 @@ public struct JsonData [DataMember(Name = "body")] public string Body { get; set; } } + public static readonly TheoryData CreateDataFromJsonTestCase = new TheoryData { { diff --git a/OpenTween/Api/BitlyApi.cs b/OpenTween/Api/BitlyApi.cs index 49dc727df..ca5897662 100644 --- a/OpenTween/Api/BitlyApi.cs +++ b/OpenTween/Api/BitlyApi.cs @@ -43,12 +43,14 @@ public class BitlyApi public string EndUserAccessToken { get; set; } = ""; public string EndUserLoginName { get; set; } = ""; + public string EndUserApiKey { get; set; } = ""; private readonly ApiKey clientId; private readonly ApiKey clientSecret; private HttpClient Http => this.localHttpClient ?? Networking.Http; + private readonly HttpClient? localHttpClient; public BitlyApi() diff --git a/OpenTween/Api/DataModel/TwitterUploadMediaResult.cs b/OpenTween/Api/DataModel/TwitterUploadMediaResult.cs index 1a57a9a22..91e10fe67 100644 --- a/OpenTween/Api/DataModel/TwitterUploadMediaResult.cs +++ b/OpenTween/Api/DataModel/TwitterUploadMediaResult.cs @@ -20,6 +20,7 @@ // Boston, MA 02110-1301, USA. #nullable enable annotations +#pragma warning disable SA1649 using System; using System.Collections.Generic; diff --git a/OpenTween/Api/MicrosoftTranslatorApi.cs b/OpenTween/Api/MicrosoftTranslatorApi.cs index 7f5e16060..e194d655c 100644 --- a/OpenTween/Api/MicrosoftTranslatorApi.cs +++ b/OpenTween/Api/MicrosoftTranslatorApi.cs @@ -42,11 +42,13 @@ public class MicrosoftTranslatorApi public static readonly Uri TranslateEndpoint = new Uri("https://api.cognitive.microsofttranslator.com/translate"); public string AccessToken { get; internal set; } = ""; + public DateTimeUtc RefreshAccessTokenAt { get; internal set; } = DateTimeUtc.MinValue; private readonly ApiKey subscriptionKey; private HttpClient Http => this.localHttpClient ?? Networking.Http; + private readonly HttpClient? localHttpClient; public MicrosoftTranslatorApi() diff --git a/OpenTween/Api/TwitterApi.cs b/OpenTween/Api/TwitterApi.cs index 2c2bda104..6e957c64a 100644 --- a/OpenTween/Api/TwitterApi.cs +++ b/OpenTween/Api/TwitterApi.cs @@ -36,6 +36,7 @@ namespace OpenTween.Api public sealed class TwitterApi : IDisposable { public long CurrentUserId { get; private set; } + public string CurrentScreenName { get; private set; } = ""; public IApiConnection Connection => this.ApiConnection ?? throw new InvalidOperationException(); diff --git a/OpenTween/Api/TwitterApiException.cs b/OpenTween/Api/TwitterApiException.cs index fd25a8e9b..28418166f 100644 --- a/OpenTween/Api/TwitterApiException.cs +++ b/OpenTween/Api/TwitterApiException.cs @@ -37,6 +37,7 @@ namespace OpenTween.Api public class TwitterApiException : WebApiException { public HttpStatusCode StatusCode { get; } + public TwitterError? ErrorResponse { get; } public TwitterErrorItem[] Errors diff --git a/OpenTween/Api/TwitterApiStatus.cs b/OpenTween/Api/TwitterApiStatus.cs index e5ad9690d..50a1348c9 100644 --- a/OpenTween/Api/TwitterApiStatus.cs +++ b/OpenTween/Api/TwitterApiStatus.cs @@ -39,7 +39,9 @@ namespace OpenTween.Api public class TwitterApiStatus { public TwitterApiAccessLevel AccessLevel { get; set; } + public EndpointLimits AccessLimit { get; } + public ApiLimit? MediaUploadLimit { get; set; } public class AccessLimitUpdatedEventArgs : EventArgs @@ -49,6 +51,7 @@ public class AccessLimitUpdatedEventArgs : EventArgs public AccessLimitUpdatedEventArgs(string? endpointName) => this.EndpointName = endpointName; } + public event EventHandler? AccessLimitUpdated; public TwitterApiStatus() diff --git a/OpenTween/AsyncTimer.cs b/OpenTween/AsyncTimer.cs index 4e3c97b87..dbda858bc 100644 --- a/OpenTween/AsyncTimer.cs +++ b/OpenTween/AsyncTimer.cs @@ -30,6 +30,7 @@ namespace OpenTween public sealed class AsyncTimer : ITimer { public TimeSpan DueTime { get; private set; } = Timeout.InfiniteTimeSpan; + public TimeSpan Period { get; private set; } = Timeout.InfiniteTimeSpan; private readonly Func callback; diff --git a/OpenTween/AtIdSupplement.cs b/OpenTween/AtIdSupplement.cs index dd4456138..97f1b5654 100644 --- a/OpenTween/AtIdSupplement.cs +++ b/OpenTween/AtIdSupplement.cs @@ -42,6 +42,7 @@ public partial class AtIdSupplement : OTBaseForm public string StartsWith { get; set; } = ""; public string InputText { get; set; } = ""; + private bool isBack = false; private readonly string startChar = ""; diff --git a/OpenTween/Connection/Networking.cs b/OpenTween/Connection/Networking.cs index 27d1f1ac0..73a666955 100644 --- a/OpenTween/Connection/Networking.cs +++ b/OpenTween/Connection/Networking.cs @@ -37,6 +37,7 @@ namespace OpenTween.Connection public static class Networking { public static TimeSpan DefaultTimeout { get; set; } + public static TimeSpan UploadImageTimeout { get; set; } /// diff --git a/OpenTween/Connection/OAuthEchoHandler.cs b/OpenTween/Connection/OAuthEchoHandler.cs index 8bc7abbc6..9e5e07e3d 100644 --- a/OpenTween/Connection/OAuthEchoHandler.cs +++ b/OpenTween/Connection/OAuthEchoHandler.cs @@ -35,6 +35,7 @@ namespace OpenTween.Connection public class OAuthEchoHandler : DelegatingHandler { public Uri AuthServiceProvider { get; } + public string VerifyCredentialsAuthorization { get; } public OAuthEchoHandler(HttpMessageHandler innerHandler, Uri authServiceProvider, string authorizationValue) diff --git a/OpenTween/Connection/OAuthHandler.cs b/OpenTween/Connection/OAuthHandler.cs index 1b46c71d3..9e0489ff3 100644 --- a/OpenTween/Connection/OAuthHandler.cs +++ b/OpenTween/Connection/OAuthHandler.cs @@ -39,8 +39,11 @@ namespace OpenTween.Connection public class OAuthHandler : DelegatingHandler { public ApiKey ConsumerKey { get; } + public ApiKey ConsumerSecret { get; } + public string AccessToken { get; } + public string AccessSecret { get; } public OAuthHandler(HttpMessageHandler innerHandler, ApiKey consumerKey, ApiKey consumerSecret, string accessToken, string accessSecret) diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index bb5c988c1..23980a431 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -52,6 +52,7 @@ public static string RestApiHost public bool IsDisposed { get; private set; } = false; public string AccessToken { get; } + public string AccessSecret { get; } internal HttpClient Http = null!; diff --git a/OpenTween/DebounceTimer.cs b/OpenTween/DebounceTimer.cs index 531853ac5..f88a040d8 100644 --- a/OpenTween/DebounceTimer.cs +++ b/OpenTween/DebounceTimer.cs @@ -44,7 +44,9 @@ public class DebounceTimer : IDisposable private bool refreshTimerEnabled; public TimeSpan Interval { get; } + public bool InvokeLeading { get; } + public bool InvokeTrailing { get; } public DebounceTimer(Func timerCallback, TimeSpan interval, bool leading, bool trailing) diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index c6440d7b3..8c90cbbec 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -45,6 +45,7 @@ public sealed class DetailsListView : ListView public ContextMenuStrip? ColumnHeaderContextMenuStrip { get; set; } public event EventHandler? VScrolled; + public event EventHandler? HScrolled; public DetailsListView() diff --git a/OpenTween/FilterDialog.cs b/OpenTween/FilterDialog.cs index dcdd0a1f1..a6df3cd6c 100644 --- a/OpenTween/FilterDialog.cs +++ b/OpenTween/FilterDialog.cs @@ -89,6 +89,7 @@ private EnableButtonMode RuleEnableButtonMode this.buttonRuleToggleEnabled.Enabled = value != EnableButtonMode.NotSelected; } } + private EnableButtonMode ruleEnableButtonMode = FilterDialog.EnableButtonMode.NotSelected; public TabModel? SelectedTab diff --git a/OpenTween/Growl.cs b/OpenTween/Growl.cs index efc5e5033..0773c7617 100644 --- a/OpenTween/Growl.cs +++ b/OpenTween/Growl.cs @@ -57,7 +57,9 @@ public class GrowlHelper public class NotifyCallbackEventArgs : EventArgs { public long StatusId { get; set; } + public NotifyType NotifyType { get; set; } + public NotifyCallbackEventArgs(NotifyType notifyType, string statusId) { if (statusId.Length > 1) diff --git a/OpenTween/HashtagManage.cs b/OpenTween/HashtagManage.cs index f3ee11551..db006fa2d 100644 --- a/OpenTween/HashtagManage.cs +++ b/OpenTween/HashtagManage.cs @@ -41,8 +41,11 @@ namespace OpenTween public partial class HashtagManage : OTBaseForm { public string UseHash { get; private set; } = ""; + public bool IsPermanent { get; private set; } = false; + public bool IsHead { get; private set; } = false; + public bool IsNotAddToAtReply { get; private set; } = true; /// diff --git a/OpenTween/HookGlobalHotkey.cs b/OpenTween/HookGlobalHotkey.cs index b29d4fc49..66460f5ec 100644 --- a/OpenTween/HookGlobalHotkey.cs +++ b/OpenTween/HookGlobalHotkey.cs @@ -37,9 +37,11 @@ namespace OpenTween public class HookGlobalHotkey : NativeWindow, IDisposable { private readonly Form targetForm; + private class KeyEventValue { public KeyEventArgs KeyEvent { get; } + public int Value { get; } public KeyEventValue(KeyEventArgs keyEvent, int value) diff --git a/OpenTween/InputTabName.cs b/OpenTween/InputTabName.cs index 50c304a76..acac6db53 100644 --- a/OpenTween/InputTabName.cs +++ b/OpenTween/InputTabName.cs @@ -74,6 +74,7 @@ public string FormDescription } public bool IsShowUsage { get; set; } + public MyCommon.TabUsageType Usage { get; set; } private void InputTabName_Load(object sender, EventArgs e) diff --git a/OpenTween/LRUCacheDictionary.cs b/OpenTween/LRUCacheDictionary.cs index cac25a8d6..403e52125 100644 --- a/OpenTween/LRUCacheDictionary.cs +++ b/OpenTween/LRUCacheDictionary.cs @@ -58,6 +58,7 @@ public class CacheRemovedEventArgs : EventArgs public CacheRemovedEventArgs(KeyValuePair item) => this.Item = item; } + public event EventHandler? CacheRemoved; internal LinkedList> InnerList; @@ -197,6 +198,7 @@ public TValue this[TKey key] return node.Value.Value; } + set { var pair = new KeyValuePair(key, value); diff --git a/OpenTween/LoginDialog.cs b/OpenTween/LoginDialog.cs index 08b00d51a..8c4cd4fcb 100644 --- a/OpenTween/LoginDialog.cs +++ b/OpenTween/LoginDialog.cs @@ -36,9 +36,11 @@ namespace OpenTween public partial class LoginDialog : OTBaseForm { public string LoginName => this.textboxLoginName.Text; + public string Password => this.textboxPassword.Text; public Func>? LoginCallback { get; set; } = null; + public bool LoginSuccessed { get; set; } = false; public LoginDialog() diff --git a/OpenTween/MediaItem.cs b/OpenTween/MediaItem.cs index a2e7dbbc8..695bc2ee1 100644 --- a/OpenTween/MediaItem.cs +++ b/OpenTween/MediaItem.cs @@ -20,6 +20,7 @@ // Boston, MA 02110-1301, USA. #nullable enable +#pragma warning disable SA1649 using System; using System.Drawing; @@ -94,6 +95,7 @@ public interface IMediaItem public class FileMediaItem : IMediaItem { public FileInfo FileInfo { get; } + public string? AltText { get; set; } public FileMediaItem(string path) @@ -186,6 +188,7 @@ public MemoryImageMediaItem(MemoryImage image) } public string Path { get; } + public string? AltText { get; set; } public string Name diff --git a/OpenTween/MediaSelector.cs b/OpenTween/MediaSelector.cs index f24b52c34..36bea22a5 100644 --- a/OpenTween/MediaSelector.cs +++ b/OpenTween/MediaSelector.cs @@ -40,9 +40,11 @@ namespace OpenTween public partial class MediaSelector : UserControl { public event EventHandler? BeginSelecting; + public event EventHandler? EndSelecting; public event EventHandler? FilePickDialogOpening; + public event EventHandler? FilePickDialogClosed; public event EventHandler? SelectedServiceChanged; @@ -103,7 +105,9 @@ public ICollection GetServices() private class SelectedMedia { public IMediaItem? Item { get; set; } + public MyCommon.UploadFileType Type { get; set; } + public string Text { get; set; } public SelectedMedia(IMediaItem? item, MyCommon.UploadFileType type, string text) diff --git a/OpenTween/Models/FilterTabModel.cs b/OpenTween/Models/FilterTabModel.cs index dd27e642c..ddf36badb 100644 --- a/OpenTween/Models/FilterTabModel.cs +++ b/OpenTween/Models/FilterTabModel.cs @@ -149,6 +149,7 @@ public PostFilterRule[] FilterArray return this.filters.ToArray(); } } + set { lock (this.lockObjFilters) diff --git a/OpenTween/Models/MediaInfo.cs b/OpenTween/Models/MediaInfo.cs index 2390e15d3..43c60b042 100644 --- a/OpenTween/Models/MediaInfo.cs +++ b/OpenTween/Models/MediaInfo.cs @@ -32,7 +32,9 @@ namespace OpenTween.Models public class MediaInfo { public string Url { get; } + public string? AltText { get; } + public string? VideoUrl { get; } public MediaInfo(string url) diff --git a/OpenTween/Models/PostClass.cs b/OpenTween/Models/PostClass.cs index add6c52cb..e196b8495 100644 --- a/OpenTween/Models/PostClass.cs +++ b/OpenTween/Models/PostClass.cs @@ -43,6 +43,7 @@ public class PostClass : ICloneable public readonly struct StatusGeo : IEquatable { public double Longitude { get; } + public double Latitude { get; } public StatusGeo(double longitude, double latitude) @@ -68,15 +69,20 @@ public bool Equals(StatusGeo other) } public string Nickname { get; set; } = ""; + public string TextFromApi { get; set; } = ""; /// スクリーンリーダーでの読み上げを考慮したテキスト public string AccessibleText { get; set; } = ""; public string ImageUrl { get; set; } = ""; + public string ScreenName { get; set; } = ""; + public DateTimeUtc CreatedAt { get; set; } + public long StatusId { get; set; } + private bool isFav; public string Text @@ -94,32 +100,56 @@ public string Text } set => this.text = value; } + private string text = ""; public bool IsRead { get; set; } + public bool IsReply { get; set; } + public bool IsExcludeReply { get; set; } + private bool isProtect; + public bool IsOwl { get; set; } + private bool isMark; + public string? InReplyToUser { get; set; } + private long? inReplyToStatusId; + public string Source { get; set; } = ""; + public Uri? SourceUri { get; set; } + public List<(long UserId, string ScreenName)> ReplyToList { get; set; } + public bool IsMe { get; set; } + public bool IsDm { get; set; } + public long UserId { get; set; } + public bool FilterHit { get; set; } + public string? RetweetedBy { get; set; } + public long? RetweetedId { get; set; } + private bool isDeleted = false; private StatusGeo? postGeo = null; + public int RetweetedCount { get; set; } + public long? RetweetedByUserId { get; set; } + public long? InReplyToUserId { get; set; } + public List Media { get; set; } + public long[] QuoteStatusIds { get; set; } + public ExpandedUrlInfo[] ExpandedUrls { get; set; } /// @@ -217,6 +247,7 @@ public bool IsFav return this.isFav; } + set { this.isFav = value; @@ -244,6 +275,7 @@ public bool IsProtect this.isProtect = value; } } + public bool IsMark { get => this.isMark; @@ -257,6 +289,7 @@ public bool IsMark this.isMark = value; } } + public long? InReplyToStatusId { get => this.inReplyToStatusId; diff --git a/OpenTween/Models/PostFilterRule.cs b/OpenTween/Models/PostFilterRule.cs index ead86ae22..ad6e52bad 100644 --- a/OpenTween/Models/PostFilterRule.cs +++ b/OpenTween/Models/PostFilterRule.cs @@ -71,6 +71,7 @@ public bool Enabled get => this.enabled; set => this.SetProperty(ref this.enabled, value); } + private bool enabled; [XmlElement("NameFilter")] @@ -79,6 +80,7 @@ public string? FilterName get => this.filterName; set => this.SetProperty(ref this.filterName, value); } + private string? filterName; [XmlElement("ExNameFilter")] @@ -87,6 +89,7 @@ public string? ExFilterName get => this.exFilterName; set => this.SetProperty(ref this.exFilterName, value); } + private string? exFilterName; [XmlArray("BodyFilterArray")] @@ -95,6 +98,7 @@ public string[] FilterBody get => this.filterBody; set => this.SetProperty(ref this.filterBody, value ?? throw new ArgumentNullException(nameof(value))); } + private string[] filterBody = Array.Empty(); [XmlArray("ExBodyFilterArray")] @@ -103,6 +107,7 @@ public string[] ExFilterBody get => this.exFilterBody; set => this.SetProperty(ref this.exFilterBody, value ?? throw new ArgumentNullException(nameof(value))); } + private string[] exFilterBody = Array.Empty(); [XmlElement("SearchBoth")] @@ -111,6 +116,7 @@ public bool UseNameField get => this.useNameField; set => this.SetProperty(ref this.useNameField, value); } + private bool useNameField; [XmlElement("ExSearchBoth")] @@ -119,6 +125,7 @@ public bool ExUseNameField get => this.exUseNameField; set => this.SetProperty(ref this.exUseNameField, value); } + private bool exUseNameField; [XmlElement("MoveFrom")] @@ -127,6 +134,7 @@ public bool MoveMatches get => this.moveMatches; set => this.SetProperty(ref this.moveMatches, value); } + private bool moveMatches; [XmlElement("SetMark")] @@ -135,6 +143,7 @@ public bool MarkMatches get => this.markMatches; set => this.SetProperty(ref this.markMatches, value); } + private bool markMatches; [XmlElement("SearchUrl")] @@ -143,6 +152,7 @@ public bool FilterByUrl get => this.filterByUrl; set => this.SetProperty(ref this.filterByUrl, value); } + private bool filterByUrl; [XmlElement("ExSearchUrl")] @@ -151,6 +161,7 @@ public bool ExFilterByUrl get => this.exFilterByUrl; set => this.SetProperty(ref this.exFilterByUrl, value); } + private bool exFilterByUrl; public bool CaseSensitive @@ -158,6 +169,7 @@ public bool CaseSensitive get => this.caseSensitive; set => this.SetProperty(ref this.caseSensitive, value); } + private bool caseSensitive; public bool ExCaseSensitive @@ -165,6 +177,7 @@ public bool ExCaseSensitive get => this.exCaseSensitive; set => this.SetProperty(ref this.exCaseSensitive, value); } + private bool exCaseSensitive; public bool UseLambda @@ -172,6 +185,7 @@ public bool UseLambda get => this.useLambda; set => this.SetProperty(ref this.useLambda, value); } + private bool useLambda; public bool ExUseLambda @@ -179,6 +193,7 @@ public bool ExUseLambda get => this.exUseLambda; set => this.SetProperty(ref this.exUseLambda, value); } + private bool exUseLambda; public bool UseRegex @@ -186,6 +201,7 @@ public bool UseRegex get => this.useRegex; set => this.SetProperty(ref this.useRegex, value); } + private bool useRegex; public bool ExUseRegex @@ -193,6 +209,7 @@ public bool ExUseRegex get => this.exUseRegex; set => this.SetProperty(ref this.exUseRegex, value); } + private bool exUseRegex; [XmlElement("IsRt")] @@ -201,6 +218,7 @@ public bool FilterRt get => this.filterRt; set => this.SetProperty(ref this.filterRt, value); } + private bool filterRt; [XmlElement("IsExRt")] @@ -209,6 +227,7 @@ public bool ExFilterRt get => this.exFilterRt; set => this.SetProperty(ref this.exFilterRt, value); } + private bool exFilterRt; [XmlElement("Source")] @@ -217,6 +236,7 @@ public string? FilterSource get => this.filterSource; set => this.SetProperty(ref this.filterSource, value); } + private string? filterSource; [XmlElement("ExSource")] @@ -225,6 +245,7 @@ public string? ExFilterSource get => this.exFilterSource; set => this.SetProperty(ref this.exFilterSource, value); } + private string? exFilterSource; public PostFilterRule() diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index 170afae29..17946c35a 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -55,6 +55,7 @@ public IReadOnlyTabCollection Tabs public Stack RemovedTab { get; } = new Stack(); public ISet BlockIds { get; set; } = new HashSet(); + public ISet MuteUserIds { get; set; } = new HashSet(); // 発言の追加 diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index f53bc1719..93071f026 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -44,14 +44,19 @@ public abstract class TabModel public string TabName { get; set; } public bool UnreadManage { get; set; } = true; + public bool Protected { get; set; } + public bool Notify { get; set; } = false; + public string SoundFile { get; set; } = ""; public ComparerMode SortMode { get; private set; } + public SortOrder SortOrder { get; private set; } public long OldestId { get; set; } = long.MaxValue; + public long SinceId { get; set; } public abstract MyCommon.TabUsageType TabType { get; } @@ -60,10 +65,13 @@ public virtual ConcurrentDictionary Posts => TabInformations.GetInstance().Posts; public int AllCount => this.ids.Count; + public long[] StatusIds => this.ids.ToArray(); public bool IsDefaultTabType => this.TabType.IsDefault(); + public bool IsDistributableTabType => this.TabType.IsDistributable(); + public bool IsInnerStorageTabType => this.TabType.IsInnerStorage(); /// @@ -108,6 +116,7 @@ protected TabModel(string tabName) private readonly struct TemporaryId { public long StatusId { get; } + public bool Read { get; } public TemporaryId(long statusId, bool read) diff --git a/OpenTween/MouseWheelMessageFilter.cs b/OpenTween/MouseWheelMessageFilter.cs index eb2e69156..2ab198b31 100644 --- a/OpenTween/MouseWheelMessageFilter.cs +++ b/OpenTween/MouseWheelMessageFilter.cs @@ -78,6 +78,7 @@ public bool PreFilterMessage(ref Message m) internal class MouseEvent { public Point ScreenLocation { get; } + public int WheelDelta { get; } public MouseEvent(Point location, int delta) diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 7e6de3be4..d5657e920 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -60,7 +60,9 @@ namespace OpenTween public static class MyCommon { private static readonly object LockObj = new object(); + public static bool EndingFlag { get; set; } // 終了フラグ + public static string SettingPath { get; set; } = null!; public enum IconSizes @@ -191,6 +193,7 @@ public enum REPLY_ICONSTATE } public static _Assembly EntryAssembly { get; internal set; } + public static string FileVersion { get; internal set; } static MyCommon() diff --git a/OpenTween/NativeMethods.cs b/OpenTween/NativeMethods.cs index 39025566a..086a0fb55 100644 --- a/OpenTween/NativeMethods.cs +++ b/OpenTween/NativeMethods.cs @@ -174,6 +174,7 @@ public enum FlashSpecification : uint FlashTimer = FLASHW_TIMER, FlashTimerNoForeground = FLASHW_TIMERNOFG, } + // http://www.atmarkit.co.jp/fdotnet/dotnettips/723flashwindow/flashwindow.html [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] @@ -243,14 +244,18 @@ public static bool IsScreenSaverRunning() #region "グローバルフック" [DllImport("user32")] private static extern int RegisterHotKey(IntPtr hwnd, int id, int fsModifiers, int vk); + [DllImport("user32")] private static extern int UnregisterHotKey(IntPtr hwnd, int id); + [DllImport("kernel32", CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)] private static extern ushort GlobalAddAtom([MarshalAs(UnmanagedType.LPTStr)] string lpString); + [DllImport("kernel32")] private static extern ushort GlobalDeleteAtom(ushort nAtom); private static int registerCount = 0; + // register a global hot key public static int RegisterGlobalHotKey(int hotkeyValue, int modifiers, Form targetForm) { diff --git a/OpenTween/OTPictureBox.cs b/OpenTween/OTPictureBox.cs index ca5b2c7b4..92b9a330b 100644 --- a/OpenTween/OTPictureBox.cs +++ b/OpenTween/OTPictureBox.cs @@ -53,6 +53,7 @@ public class OTPictureBox : PictureBox this.RestoreSizeMode(); } } + private MemoryImage? memoryImage; [Localizable(true)] diff --git a/OpenTween/OTSplitContainer.cs b/OpenTween/OTSplitContainer.cs index 4a73651ac..de63fcc62 100644 --- a/OpenTween/OTSplitContainer.cs +++ b/OpenTween/OTSplitContainer.cs @@ -75,6 +75,7 @@ public bool IsPanelInverted } } } + private bool isPanelInverted = false; /// @@ -107,6 +108,7 @@ private int SplitterTotalWidth else return base.FixedPanel; } + set { if (value != FixedPanel.None && this.IsPanelInverted) @@ -128,6 +130,7 @@ private int SplitterTotalWidth else return base.SplitterDistance; } + set { if (this.IsPanelInverted) diff --git a/OpenTween/OpenURL.cs b/OpenTween/OpenURL.cs index 7bff34d81..064f621ab 100644 --- a/OpenTween/OpenURL.cs +++ b/OpenTween/OpenURL.cs @@ -152,6 +152,7 @@ public override string ToString() => this.Href; public string Url { get; } + public string Href { get; } } } diff --git a/OpenTween/PostStatusParams.cs b/OpenTween/PostStatusParams.cs index 705f57359..971e226d9 100644 --- a/OpenTween/PostStatusParams.cs +++ b/OpenTween/PostStatusParams.cs @@ -33,10 +33,15 @@ namespace OpenTween public class PostStatusParams { public string Text { get; set; } = ""; + public long? InReplyToStatusId { get; set; } + public IReadOnlyList MediaIds { get; set; } = Array.Empty(); + public bool AutoPopulateReplyMetadata { get; set; } + public IReadOnlyList ExcludeReplyUserIds { get; set; } = Array.Empty(); + public string? AttachmentUrl { get; set; } } } diff --git a/OpenTween/SearchWordDialog.cs b/OpenTween/SearchWordDialog.cs index efdd3328f..ea77868c7 100644 --- a/OpenTween/SearchWordDialog.cs +++ b/OpenTween/SearchWordDialog.cs @@ -54,11 +54,14 @@ public enum SearchType public class SearchOptions { public SearchType Type { get; } + public string Query { get; } // タイムライン内検索のみで使用する public bool NewTab { get; } + public bool CaseSensitive { get; } + public bool UseRegex { get; } public SearchOptions(SearchType type, string query, bool newTab, bool caseSensitive, bool useRegex) @@ -72,6 +75,7 @@ public SearchOptions(SearchType type, string query, bool newTab, bool caseSensit } private SearchOptions? resultOptions = null; + public SearchOptions? ResultOptions { get => this.resultOptions; @@ -104,6 +108,7 @@ public SearchOptions? ResultOptions } private bool disableNetTabButton = false; + public bool DisableNewTabButton { get => this.disableNetTabButton; diff --git a/OpenTween/SendErrorReportForm.cs b/OpenTween/SendErrorReportForm.cs index 40a25ce4a..c08f947e2 100644 --- a/OpenTween/SendErrorReportForm.cs +++ b/OpenTween/SendErrorReportForm.cs @@ -49,6 +49,7 @@ public ErrorReport ErrorReport this.bindingSource.DataSource = value; } } + private ErrorReport errorReport = null!; public SendErrorReportForm() @@ -101,6 +102,7 @@ public string ReportText this.UpdateEncodedReport(); } } + private string reportText = ""; public bool AnonymousReport @@ -112,6 +114,7 @@ public bool AnonymousReport this.UpdateEncodedReport(); } } + private bool anonymousReport = true; public bool CanSendByDM @@ -119,6 +122,7 @@ public bool CanSendByDM get => this.canSendByDm; private set => this.SetProperty(ref this.canSendByDm, value); } + private bool canSendByDm; public string EncodedReportForDM @@ -126,6 +130,7 @@ public string EncodedReportForDM get => this.encodedReportForDM; private set => this.SetProperty(ref this.encodedReportForDM, value); } + private string encodedReportForDM = ""; private readonly Twitter? tw; diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index 724d0cdf2..0268e3520 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -49,6 +49,7 @@ public void Save() [XmlIgnore] public string Password = ""; + public string EncryptPassword { get => this.Encrypt(this.Password); @@ -58,6 +59,7 @@ public string EncryptPassword public string Token = ""; [XmlIgnore] public string TokenSecret = ""; + public string EncryptTokenSecret { get => this.Encrypt(this.TokenSecret); @@ -83,6 +85,7 @@ private string Encrypt(string password) return ""; } } + private string Decrypt(string password) { if (MyCommon.IsNullOrEmpty(password)) password = ""; @@ -256,11 +259,13 @@ public class UserAccount public string Token = ""; [XmlIgnore] public string TokenSecret = ""; + public string EncryptTokenSecret { get => this.Encrypt(this.TokenSecret); set => this.TokenSecret = this.Decrypt(value); } + private string Encrypt(string password) { if (MyCommon.IsNullOrEmpty(password)) password = ""; @@ -280,6 +285,7 @@ private string Encrypt(string password) return ""; } } + private string Decrypt(string password) { if (MyCommon.IsNullOrEmpty(password)) password = ""; diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index 347e079b7..872fbbaa3 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -88,6 +88,7 @@ public void Save() [XmlIgnore] public Font FontUnread = new Font(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline); + public string FontUnreadStr { get => this.FontToString(this.FontUnread); @@ -96,6 +97,7 @@ public string FontUnreadStr [XmlIgnore] public Color ColorUnread = System.Drawing.SystemColors.ControlText; + public string ColorUnreadStr { get => this.ColorToString(this.ColorUnread); @@ -104,6 +106,7 @@ public string ColorUnreadStr [XmlIgnore] public Font FontRead = System.Drawing.SystemFonts.DefaultFont; + public string FontReadStr { get => this.FontToString(this.FontRead); @@ -112,6 +115,7 @@ public string FontReadStr [XmlIgnore] public Color ColorRead = System.Drawing.SystemColors.ControlText; + public string ColorReadStr { get => this.ColorToString(this.ColorRead); @@ -120,6 +124,7 @@ public string ColorReadStr [XmlIgnore] public Color ColorFav = Color.FromKnownColor(System.Drawing.KnownColor.Red); + public string ColorFavStr { get => this.ColorToString(this.ColorFav); @@ -128,6 +133,7 @@ public string ColorFavStr [XmlIgnore] public Color ColorOWL = Color.FromKnownColor(System.Drawing.KnownColor.Blue); + public string ColorOWLStr { get => this.ColorToString(this.ColorOWL); @@ -136,6 +142,7 @@ public string ColorOWLStr [XmlIgnore] public Color ColorRetweet = Color.FromKnownColor(System.Drawing.KnownColor.Green); + public string ColorRetweetStr { get => this.ColorToString(this.ColorRetweet); @@ -144,6 +151,7 @@ public string ColorRetweetStr [XmlIgnore] public Font FontDetail = System.Drawing.SystemFonts.DefaultFont; + public string FontDetailStr { get => this.FontToString(this.FontDetail); @@ -152,6 +160,7 @@ public string FontDetailStr [XmlIgnore] public Color ColorSelf = Color.FromKnownColor(System.Drawing.KnownColor.AliceBlue); + public string ColorSelfStr { get => this.ColorToString(this.ColorSelf); @@ -160,6 +169,7 @@ public string ColorSelfStr [XmlIgnore] public Color ColorAtSelf = Color.FromKnownColor(System.Drawing.KnownColor.AntiqueWhite); + public string ColorAtSelfStr { get => this.ColorToString(this.ColorAtSelf); @@ -168,6 +178,7 @@ public string ColorAtSelfStr [XmlIgnore] public Color ColorTarget = Color.FromKnownColor(System.Drawing.KnownColor.LemonChiffon); + public string ColorTargetStr { get => this.ColorToString(this.ColorTarget); @@ -176,6 +187,7 @@ public string ColorTargetStr [XmlIgnore] public Color ColorAtTarget = Color.FromKnownColor(System.Drawing.KnownColor.LavenderBlush); + public string ColorAtTargetStr { get => this.ColorToString(this.ColorAtTarget); @@ -184,6 +196,7 @@ public string ColorAtTargetStr [XmlIgnore] public Color ColorAtFromTarget = Color.FromKnownColor(System.Drawing.KnownColor.Honeydew); + public string ColorAtFromTargetStr { get => this.ColorToString(this.ColorAtFromTarget); @@ -192,6 +205,7 @@ public string ColorAtFromTargetStr [XmlIgnore] public Color ColorAtTo = Color.FromKnownColor(System.Drawing.KnownColor.Pink); + public string ColorAtToStr { get => this.ColorToString(this.ColorAtTo); @@ -200,6 +214,7 @@ public string ColorAtToStr [XmlIgnore] public Color ColorInputBackcolor = Color.FromKnownColor(System.Drawing.KnownColor.LemonChiffon); + public string ColorInputBackcolorStr { get => this.ColorToString(this.ColorInputBackcolor); @@ -208,6 +223,7 @@ public string ColorInputBackcolorStr [XmlIgnore] public Color ColorInputFont = Color.FromKnownColor(System.Drawing.KnownColor.ControlText); + public string ColorInputFontStr { get => this.ColorToString(this.ColorInputFont); @@ -216,6 +232,7 @@ public string ColorInputFontStr [XmlIgnore] public Font FontInputFont = System.Drawing.SystemFonts.DefaultFont; + public string FontInputFontStr { get => this.FontToString(this.FontInputFont); @@ -224,6 +241,7 @@ public string FontInputFontStr [XmlIgnore] public Color ColorListBackcolor = Color.FromKnownColor(System.Drawing.KnownColor.Window); + public string ColorListBackcolorStr { get => this.ColorToString(this.ColorListBackcolor); @@ -232,6 +250,7 @@ public string ColorListBackcolorStr [XmlIgnore] public Color ColorDetailBackcolor = Color.FromKnownColor(System.Drawing.KnownColor.Window); + public string ColorDetailBackcolorStr { get => this.ColorToString(this.ColorDetailBackcolor); @@ -240,6 +259,7 @@ public string ColorDetailBackcolorStr [XmlIgnore] public Color ColorDetail = Color.FromKnownColor(System.Drawing.KnownColor.ControlText); + public string ColorDetailStr { get => this.ColorToString(this.ColorDetail); @@ -248,6 +268,7 @@ public string ColorDetailStr [XmlIgnore] public Color ColorDetailLink = Color.FromKnownColor(System.Drawing.KnownColor.Blue); + public string ColorDetailLinkStr { get => this.ColorToString(this.ColorDetailLink); @@ -271,6 +292,7 @@ public string? FontUIGlobalStr [XmlIgnore] public string ProxyPassword = ""; + public string EncryptProxyPassword { get @@ -293,6 +315,7 @@ public string EncryptProxyPassword return ""; } } + set { var pwd = value; diff --git a/OpenTween/ShortUrl.cs b/OpenTween/ShortUrl.cs index 896fc7006..dcb4046aa 100644 --- a/OpenTween/ShortUrl.cs +++ b/OpenTween/ShortUrl.cs @@ -66,7 +66,9 @@ public static ShortUrl Instance public int PurgeCount { get; set; } public string BitlyAccessToken { get; set; } = ""; + public string BitlyId { get; set; } = ""; + public string BitlyKey { get; set; } = ""; private HttpClient http; diff --git a/OpenTween/TabsDialog.cs b/OpenTween/TabsDialog.cs index 4d74271ea..4f39e47a3 100644 --- a/OpenTween/TabsDialog.cs +++ b/OpenTween/TabsDialog.cs @@ -38,6 +38,7 @@ public partial class TabsDialog : OTBaseForm private readonly TabInformations tabInfo; private bool multiSelect = false; + public bool MultiSelect { get => this.multiSelect; @@ -51,6 +52,7 @@ public bool MultiSelect protected internal class TabListItem { public FilterTabModel? Tab { get; set; } + public string Label { get; set; } = ""; public override string ToString() diff --git a/OpenTween/Thumbnail/MapThumb.cs b/OpenTween/Thumbnail/MapThumb.cs index cb4a1b0a6..764cac14f 100644 --- a/OpenTween/Thumbnail/MapThumb.cs +++ b/OpenTween/Thumbnail/MapThumb.cs @@ -35,6 +35,7 @@ namespace OpenTween.Thumbnail public class GlobalLocation { public double Latitude { get; set; } + public double Longitude { get; set; } } diff --git a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs index 766244561..c7a612309 100644 --- a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs +++ b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs @@ -97,6 +97,7 @@ public bool AutoUpdate this.autoUpdate = value; } } + private bool autoUpdate = false; /// diff --git a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs index 387f40a27..a45474cb9 100644 --- a/OpenTween/Thumbnail/Services/MetaThumbnailService.cs +++ b/OpenTween/Thumbnail/Services/MetaThumbnailService.cs @@ -45,6 +45,7 @@ public class MetaThumbnailService : IThumbnailService new Regex(".+?)[\"'] (content|value)=[\"'](?[^>]+?)[\"']"), new Regex("[^>]+?)[\"'] (name|property)=[\"'](?.+?)[\"']"), }; + protected static string[] defaultPropertyNames = { "og:image", "twitter:image", "twitter:image:src" }; protected HttpClient Http diff --git a/OpenTween/TimelineScheduler.cs b/OpenTween/TimelineScheduler.cs index fc8016906..99b8daf71 100644 --- a/OpenTween/TimelineScheduler.cs +++ b/OpenTween/TimelineScheduler.cs @@ -64,6 +64,7 @@ public bool Enabled } public DateTimeUtc SystemResumedAt { get; private set; } = DateTimeUtc.MinValue; + public TimeSpan UpdateAfterSystemResume { get; set; } = Timeout.InfiniteTimeSpan; public bool EnableUpdateSystemResume diff --git a/OpenTween/ToolStripAPIGauge.cs b/OpenTween/ToolStripAPIGauge.cs index 4ac430573..2eaa8e1b4 100644 --- a/OpenTween/ToolStripAPIGauge.cs +++ b/OpenTween/ToolStripAPIGauge.cs @@ -62,6 +62,7 @@ public int GaugeHeight this.Invalidate(); } } + private int gaugeHeight = 8; /// @@ -81,6 +82,7 @@ private set this.Invalidate(); } } + private ApiLimit? apiLimit = null; /// @@ -119,6 +121,7 @@ public string? ApiEndpoint } } } + private string? apiEndpoint = null; [Browsable(false)] diff --git a/OpenTween/ToolStripLabelHistory.cs b/OpenTween/ToolStripLabelHistory.cs index 51238fc43..f254cb9cb 100644 --- a/OpenTween/ToolStripLabelHistory.cs +++ b/OpenTween/ToolStripLabelHistory.cs @@ -51,8 +51,11 @@ public enum LogLevel public class LogEntry { public LogLevel LogLevel { get; } + public DateTimeUtc Timestamp { get; } + public string Summary { get; } + public string Detail { get; } public LogEntry(LogLevel logLevel, DateTimeUtc timestamp, string summary, string detail) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 15f5e2eb5..6f4115943 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -117,7 +117,9 @@ public partial class TweenMain : OTBaseForm + ".quote-tweet-link {color: inherit !important; text-decoration: none;}" + "-->" + "
";
+
         private const string DetailHtmlFormatFooterMono = "
"; + private const string DetailHtmlFormatHeaderColor = "" + "" + "

"; + private const string DetailHtmlFormatFooterColor = "

"; private string detailHtmlFormatHeader = null!; private string detailHtmlFormatFooter = null!; @@ -427,15 +430,18 @@ internal enum SEARCHTYPE private class StatusTextHistory { public string Status { get; } = ""; + public (long StatusId, string ScreenName)? InReplyTo { get; } = null; /// 画像投稿サービス名 public string ImageService { get; set; } = ""; public IMediaItem[]? MediaItems { get; set; } = null; + public StatusTextHistory() { } + public StatusTextHistory(string status, (long StatusId, string ScreenName)? inReplyTo) { this.Status = status; @@ -791,7 +797,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.ignoreConfigSave = true; this.Visible = false; - if (MyApplication.StartupOptions.ContainsKey("d")) + if (ApplicationEvents.StartupOptions.ContainsKey("d")) MyCommon.TraceFlag = true; this.InitializeTraceFrag(); @@ -825,7 +831,7 @@ private void TweenMain_Load(object sender, EventArgs e) } // 不正値チェック - if (!MyApplication.StartupOptions.ContainsKey("nolimit")) + if (!ApplicationEvents.StartupOptions.ContainsKey("nolimit")) { if (SettingManager.Common.TimelinePeriod < 15 && SettingManager.Common.TimelinePeriod > 0) SettingManager.Common.TimelinePeriod = 15; @@ -1485,6 +1491,7 @@ private void RefreshTimeline() internal struct ListViewScroll { public ScrollLockMode ScrollLockMode { get; set; } + public long? TopItemStatusId { get; set; } } @@ -1565,7 +1572,9 @@ private ScrollLockMode GetScrollLockMode(DetailsListView listView) internal struct ListViewSelection { public long[]? SelectedStatusIds { get; set; } + public long? SelectionMarkStatusId { get; set; } + public long? FocusedStatusId { get; set; } } @@ -5396,7 +5405,9 @@ private void RunTweenUp() public class VersionInfo { public Version Version { get; } + public Uri DownloadUri { get; } + public string ReleaseNote { get; } public VersionInfo(Version version, Uri downloadUri, string releaseNote) @@ -10754,6 +10765,7 @@ private async void RtCountMenuItem_Click(object sender, EventArgs e) } private readonly HookGlobalHotkey hookGlobalHotkey; + public TweenMain() { this.hookGlobalHotkey = new HookGlobalHotkey(this); @@ -10907,7 +10919,9 @@ private void ListManageToolStripMenuItem_Click(object sender, EventArgs e) } private bool ModifySettingCommon { get; set; } + private bool ModifySettingLocal { get; set; } + private bool ModifySettingAtId { get; set; } private void MenuItemCommand_DropDownOpening(object sender, EventArgs e) diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index 4a7e48e6a..6d6b00c1a 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -47,7 +47,9 @@ public partial class TweetThumbnail : UserControl protected MouseWheelMessageFilter filter = new MouseWheelMessageFilter(); public event EventHandler? ThumbnailLoading; + public event EventHandler? ThumbnailDoubleClick; + public event EventHandler? ThumbnailImageSearchClick; public ThumbnailInfo Thumbnail diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 365cb4ff4..312560b93 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -105,6 +105,7 @@ public class Twitter : IDisposable UrlValidPathEndingChars + ")|(?:@" + UrlValidGeneralPathChars + "+/)" + ")"; + private const string Qry = @"(?\?[a-z0-9!?*'();:&=+$/%#\[\]\-_.,~|]*[a-z0-9_&=#/])?"; public const string RgUrl = @"(?" + UrlValidPrecedingChars + ")" + "(?(?https?://)?" + @@ -155,13 +156,17 @@ public class Twitter : IDisposable public static readonly Regex DMSendTextRegex = new Regex(@"^DM? +(?[a-zA-Z0-9_]+) +(?.*)", RegexOptions.IgnoreCase | RegexOptions.Singleline); public TwitterApi Api { get; } + public TwitterConfiguration Configuration { get; private set; } + public TwitterTextConfiguration TextConfiguration { get; private set; } public bool GetFollowersSuccess { get; private set; } = false; + public bool GetNoRetweetSuccess { get; private set; } = false; private delegate void GetIconImageDelegate(PostClass post); + private readonly object lockObj = new object(); private ISet followerId = new HashSet(); private long[] noRTId = Array.Empty(); @@ -429,13 +434,19 @@ public long UserId => this.Api.CurrentUserId; public static MyCommon.ACCOUNT_STATE AccountState { get; set; } = MyCommon.ACCOUNT_STATE.Valid; + public bool RestrictFavCheck { get; set; } + public bool ReadOwnPost { get; set; } public int FollowersCount { get; private set; } + public int FriendsCount { get; private set; } + public int StatusesCount { get; private set; } + public string Location { get; private set; } = ""; + public string Bio { get; private set; } = ""; /// ユーザーのフォロワー数などの情報を更新します diff --git a/OpenTween/UserInfo.cs b/OpenTween/UserInfo.cs index 689256a92..69f57d19f 100644 --- a/OpenTween/UserInfo.cs +++ b/OpenTween/UserInfo.cs @@ -67,6 +67,7 @@ public UserInfo(TwitterUser user) this.PostSource = user.Status.Source; } } + public long Id = 0; public string Name = ""; public string ScreenName = ""; From 8b705f0d08de3ccc24d16faccad44331f5186986 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 08:11:59 +0900 Subject: [PATCH 109/402] =?UTF-8?q?=E3=83=96=E3=83=AD=E3=83=83=E3=82=AF?= =?UTF-8?q?=E3=81=AE=E6=8B=AC=E5=BC=A7=E3=82=92=E8=BF=BD=E5=8A=A0=20(SA151?= =?UTF-8?q?9,=20SA1520)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Connection/Networking.cs | 2 ++ OpenTween/Connection/OAuthUtility.cs | 2 ++ OpenTween/DetailsListView.cs | 5 +++++ OpenTween/ListManage.cs | 2 ++ OpenTween/Tween.cs | 8 ++++++++ OpenTween/TweetFormatter.cs | 4 ++++ OpenTween/Twitter.cs | 2 ++ 7 files changed, 25 insertions(+) diff --git a/OpenTween/Connection/Networking.cs b/OpenTween/Connection/Networking.cs index 73a666955..4dca4fa1c 100644 --- a/OpenTween/Connection/Networking.cs +++ b/OpenTween/Connection/Networking.cs @@ -227,8 +227,10 @@ public ForceIPv4Handler(HttpMessageHandler innerHandler) : base(innerHandler) { foreach (var address in Dns.GetHostAddresses("pbs.twimg.com")) + { if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) this.ipv4Address = address; + } } protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) diff --git a/OpenTween/Connection/OAuthUtility.cs b/OpenTween/Connection/OAuthUtility.cs index c600f819a..0e98f7113 100644 --- a/OpenTween/Connection/OAuthUtility.cs +++ b/OpenTween/Connection/OAuthUtility.cs @@ -69,8 +69,10 @@ public static string CreateAuthorization( var parameter = GetOAuthParameter(consumerKey, token); // OAuth共通情報にquery情報を追加 if (query != null) + { foreach (var (key, value) in query) parameter.Add(key, value); + } // 署名の作成・追加 parameter.Add("oauth_signature", CreateSignature(consumerSecret, tokenSecret, httpMethod, requestUri, parameter)); // HTTPリクエストのヘッダに追加 diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index 8c90cbbec..097982c7e 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -252,11 +252,16 @@ protected override void WndProc(ref Message m) if (this.IsDisposed) return; if (vPos != -1) + { if (vPos != NativeMethods.GetScrollPosition(this, NativeMethods.ScrollBarDirection.SB_VERT)) this.VScrolled?.Invoke(this, EventArgs.Empty); + } + if (hPos != -1) + { if (hPos != NativeMethods.GetScrollPosition(this, NativeMethods.ScrollBarDirection.SB_HORZ)) this.HScrolled?.Invoke(this, EventArgs.Empty); + } } } } diff --git a/OpenTween/ListManage.cs b/OpenTween/ListManage.cs index 02807e969..0817c432b 100644 --- a/OpenTween/ListManage.cs +++ b/OpenTween/ListManage.cs @@ -170,8 +170,10 @@ private void CancelEditButton_Click(object sender, EventArgs e) this.EditCheckBox.Checked = false; for (var i = this.ListsList.Items.Count - 1; i >= 0; i--) + { if (this.ListsList.Items[i] is NewListElement) this.ListsList.Items.RemoveAt(i); + } this.ListsList_SelectedIndexChanged(this.ListsList, EventArgs.Empty); } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 6f4115943..80d6d5289 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2674,7 +2674,9 @@ await Task.Run(async () => // TLに反映 if (SettingManager.Common.PostAndGet) + { await this.RefreshTabAsync(); + } else { if (post != null) @@ -2754,7 +2756,9 @@ await Task.Run(async () => posts.ForEach(post => this.statuses.AddPost(post)); if (SettingManager.Common.PostAndGet) + { await this.RefreshTabAsync(); + } else { this.statuses.DistributePosts(); @@ -3317,15 +3321,19 @@ await this.twitterApi.StatusesDestroy(post.StatusId) if (post.UserId == this.tw.UserId) { if (post.RetweetedId != null) + { // 他人に RT された自分のツイート // => RT 元の自分のツイートを削除 await this.twitterApi.StatusesDestroy(post.RetweetedId.Value) .IgnoreResponse(); + } else + { // 自分のツイート // => ツイートを削除 await this.twitterApi.StatusesDestroy(post.StatusId) .IgnoreResponse(); + } } } } diff --git a/OpenTween/TweetFormatter.cs b/OpenTween/TweetFormatter.cs index 7001c1f59..eb066abf3 100644 --- a/OpenTween/TweetFormatter.cs +++ b/OpenTween/TweetFormatter.cs @@ -104,15 +104,19 @@ private static IEnumerable FixEntityIndices(string text, IEnumera var endIndex = entity.Indices[1]; for (var i = curIndex; i < (startIndex + indexOffset); i++) + { if (i + 1 < text.Length && char.IsSurrogatePair(text[i], text[i + 1])) indexOffset++; + } startIndex += indexOffset; curIndex = startIndex; for (var i = curIndex; i < (endIndex + indexOffset); i++) + { if (i + 1 < text.Length && char.IsSurrogatePair(text[i], text[i + 1])) indexOffset++; + } endIndex += indexOffset; curIndex = endIndex; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 312560b93..0d51cecb0 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1540,7 +1540,9 @@ private void ExtractEntities(TwitterEntities? entities, List<(long UserId, strin media.Add(new MediaInfo(ent.MediaUrlHttps, ent.AltText, ent.ExpandedUrl)); } else + { media.Add(new MediaInfo(ent.MediaUrlHttps, ent.AltText, videoUrl: null)); + } } } } From f8ea3a0c90afb336adec0ea990f7b0e160aefda8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 08:32:04 +0900 Subject: [PATCH 110/402] =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E5=90=8D=E3=81=A8=E3=82=AF=E3=83=A9=E3=82=B9=E5=90=8D=E3=81=AE?= =?UTF-8?q?=E4=B8=8D=E4=B8=80=E8=87=B4=E3=82=92=E4=BF=AE=E6=AD=A3=20(SA164?= =?UTF-8?q?9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...Test.cs => TwitterMessageEventListTest.cs} | 0 OpenTween.Tests/Api/MobypictureApiTest.cs | 2 +- ...cationTest.cs => ApplicationEventsTest.cs} | 18 +- OpenTween/Api/DataModel/TwitterEntities.cs | 79 ++++ OpenTween/Api/DataModel/TwitterEntity.cs | 44 --- .../Api/DataModel/TwitterMessageEvent.cs | 33 -- .../Api/DataModel/TwitterMessageEventList.cs | 65 +++ .../Api/DataModel/TwitterStreamMessage.cs | 1 + OpenTween/ApplicationEvents.cs | 2 +- OpenTween/{Growl.cs => GrowlHelper.cs} | 0 ...ntroller.cs => InternetSecurityManager.cs} | 370 +++++++++--------- OpenTween/NullableAttributes.cs | 1 + OpenTween/OpenTween.csproj | 8 +- OpenTween/ReaderWriterLockTransaction.cs | 1 + OpenTween/Thumbnail/MapThumb.cs | 26 +- 15 files changed, 361 insertions(+), 289 deletions(-) rename OpenTween.Tests/Api/DataModel/{TwitterMessageEventTest.cs => TwitterMessageEventListTest.cs} (100%) rename OpenTween.Tests/{MyApplicationTest.cs => ApplicationEventsTest.cs} (85%) create mode 100644 OpenTween/Api/DataModel/TwitterEntities.cs create mode 100644 OpenTween/Api/DataModel/TwitterMessageEventList.cs rename OpenTween/{Growl.cs => GrowlHelper.cs} (100%) rename OpenTween/{WebBrowserController.cs => InternetSecurityManager.cs} (99%) diff --git a/OpenTween.Tests/Api/DataModel/TwitterMessageEventTest.cs b/OpenTween.Tests/Api/DataModel/TwitterMessageEventListTest.cs similarity index 100% rename from OpenTween.Tests/Api/DataModel/TwitterMessageEventTest.cs rename to OpenTween.Tests/Api/DataModel/TwitterMessageEventListTest.cs diff --git a/OpenTween.Tests/Api/MobypictureApiTest.cs b/OpenTween.Tests/Api/MobypictureApiTest.cs index cbde60a5b..42f45a490 100644 --- a/OpenTween.Tests/Api/MobypictureApiTest.cs +++ b/OpenTween.Tests/Api/MobypictureApiTest.cs @@ -30,7 +30,7 @@ namespace OpenTween.Api { - public class MobypictureApiText + public class MobypictureApiTest { [Fact] public async Task UploadFileAsync_Test() diff --git a/OpenTween.Tests/MyApplicationTest.cs b/OpenTween.Tests/ApplicationEventsTest.cs similarity index 85% rename from OpenTween.Tests/MyApplicationTest.cs rename to OpenTween.Tests/ApplicationEventsTest.cs index 7457f52c4..6472dc973 100644 --- a/OpenTween.Tests/MyApplicationTest.cs +++ b/OpenTween.Tests/ApplicationEventsTest.cs @@ -29,14 +29,14 @@ namespace OpenTween { - public class MyApplicationTest + public class ApplicationEventsTest { [Fact] public void ParseArguments_NoOptionsTest() { var args = new string[] { }; - Assert.Empty(MyApplication.ParseArguments(args)); + Assert.Empty(ApplicationEvents.ParseArguments(args)); } [Fact] @@ -48,7 +48,7 @@ public void ParseArguments_SingleOptionTest() { ["foo"] = "", }, - MyApplication.ParseArguments(args)); + ApplicationEvents.ParseArguments(args)); } [Fact] @@ -61,7 +61,7 @@ public void ParseArguments_MultipleOptionsTest() ["foo"] = "", ["bar"] = "", }, - MyApplication.ParseArguments(args)); + ApplicationEvents.ParseArguments(args)); } [Fact] @@ -73,7 +73,7 @@ public void ParseArguments_OptionWithArgumentTest() { ["foo"] = "hogehoge", }, - MyApplication.ParseArguments(args)); + ApplicationEvents.ParseArguments(args)); } [Fact] @@ -85,7 +85,7 @@ public void ParseArguments_OptionWithEmptyArgumentTest() { ["foo"] = "", }, - MyApplication.ParseArguments(args)); + ApplicationEvents.ParseArguments(args)); } [Fact] @@ -93,7 +93,7 @@ public void ParseArguments_IgroreInvalidOptionsTest() { var args = new string[] { "--foo", "/" }; - Assert.Empty(MyApplication.ParseArguments(args)); + Assert.Empty(ApplicationEvents.ParseArguments(args)); } [Fact] @@ -105,7 +105,7 @@ public void ParseArguments_DuplicateOptionsTest() { ["foo"] = "123", }, - MyApplication.ParseArguments(args)); + ApplicationEvents.ParseArguments(args)); } [Theory] @@ -115,7 +115,7 @@ public void ParseArguments_DuplicateOptionsTest() [InlineData("zh-TW", "en")] public void GetPreferredCulture_Test(string currentCulture, string expectedCulture) { - var actual = MyApplication.GetPreferredCulture(new CultureInfo(currentCulture)); + var actual = ApplicationEvents.GetPreferredCulture(new CultureInfo(currentCulture)); Assert.Equal(expectedCulture, actual.Name); } } diff --git a/OpenTween/Api/DataModel/TwitterEntities.cs b/OpenTween/Api/DataModel/TwitterEntities.cs new file mode 100644 index 000000000..83b77d53b --- /dev/null +++ b/OpenTween/Api/DataModel/TwitterEntities.cs @@ -0,0 +1,79 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2014 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +#nullable enable annotations + +namespace OpenTween.Api.DataModel +{ + // 参照: https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/entities-object + + [DataContract] + public class TwitterEntities : IEnumerable + { + [DataMember(Name = "hashtags", IsRequired = false)] + public TwitterEntityHashtag[]? Hashtags { get; set; } + + [DataMember(Name = "media", IsRequired = false)] + public TwitterEntityMedia[]? Media { get; set; } + + [DataMember(Name = "symbols", IsRequired = false)] + public TwitterEntitySymbol[]? Symbols { get; set; } + + [DataMember(Name = "urls", IsRequired = false)] + public TwitterEntityUrl[]? Urls { get; set; } + + [DataMember(Name = "user_mentions", IsRequired = false)] + public TwitterEntityMention[]? UserMentions { get; set; } + + public IEnumerator GetEnumerator() + { + var entities = Enumerable.Empty(); + + if (this.Hashtags != null) + entities = entities.Concat(this.Hashtags); + + if (this.Media != null) + entities = entities.Concat(this.Media); + + if (this.Symbols != null) + entities = entities.Concat(this.Symbols); + + if (this.Urls != null) + entities = entities.Concat(this.Urls); + + if (this.UserMentions != null) + entities = entities.Concat(this.UserMentions); + + return entities.GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + => this.GetEnumerator(); + } +} diff --git a/OpenTween/Api/DataModel/TwitterEntity.cs b/OpenTween/Api/DataModel/TwitterEntity.cs index 0220aba37..cd7e2e0cf 100644 --- a/OpenTween/Api/DataModel/TwitterEntity.cs +++ b/OpenTween/Api/DataModel/TwitterEntity.cs @@ -33,50 +33,6 @@ namespace OpenTween.Api.DataModel { // 参照: https://developer.twitter.com/en/docs/tweets/data-dictionary/overview/entities-object - [DataContract] - public class TwitterEntities : IEnumerable - { - [DataMember(Name = "hashtags", IsRequired = false)] - public TwitterEntityHashtag[]? Hashtags { get; set; } - - [DataMember(Name = "media", IsRequired = false)] - public TwitterEntityMedia[]? Media { get; set; } - - [DataMember(Name = "symbols", IsRequired = false)] - public TwitterEntitySymbol[]? Symbols { get; set; } - - [DataMember(Name = "urls", IsRequired = false)] - public TwitterEntityUrl[]? Urls { get; set; } - - [DataMember(Name = "user_mentions", IsRequired = false)] - public TwitterEntityMention[]? UserMentions { get; set; } - - public IEnumerator GetEnumerator() - { - var entities = Enumerable.Empty(); - - if (this.Hashtags != null) - entities = entities.Concat(this.Hashtags); - - if (this.Media != null) - entities = entities.Concat(this.Media); - - if (this.Symbols != null) - entities = entities.Concat(this.Symbols); - - if (this.Urls != null) - entities = entities.Concat(this.Urls); - - if (this.UserMentions != null) - entities = entities.Concat(this.UserMentions); - - return entities.GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - => this.GetEnumerator(); - } - [DataContract] public abstract class TwitterEntity { diff --git a/OpenTween/Api/DataModel/TwitterMessageEvent.cs b/OpenTween/Api/DataModel/TwitterMessageEvent.cs index c1883aa63..129041195 100644 --- a/OpenTween/Api/DataModel/TwitterMessageEvent.cs +++ b/OpenTween/Api/DataModel/TwitterMessageEvent.cs @@ -27,39 +27,6 @@ namespace OpenTween.Api.DataModel { - [DataContract] - public class TwitterMessageEventList - { - [DataMember(Name = "apps")] - public Dictionary Apps { get; set; } - - [DataContract] - public class App - { - [DataMember(Name = "id")] - public string Id { get; set; } - - [DataMember(Name = "name")] - public string Name { get; set; } - - [DataMember(Name = "url")] - public string Url { get; set; } - } - - [DataMember(Name = "events")] - public TwitterMessageEvent[] Events { get; set; } - - [DataMember(Name = "next_cursor", IsRequired = false)] - public string? NextCursor { get; set; } - } - - [DataContract] - public class TwitterMessageEventSingle - { - [DataMember(Name = "event")] - public TwitterMessageEvent Event { get; set; } - } - [DataContract] public class TwitterMessageEvent { diff --git a/OpenTween/Api/DataModel/TwitterMessageEventList.cs b/OpenTween/Api/DataModel/TwitterMessageEventList.cs new file mode 100644 index 000000000..ecae1719a --- /dev/null +++ b/OpenTween/Api/DataModel/TwitterMessageEventList.cs @@ -0,0 +1,65 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2018 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable annotations + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace OpenTween.Api.DataModel +{ + [DataContract] + public class TwitterMessageEventList + { + [DataMember(Name = "apps")] + public Dictionary Apps { get; set; } + + [DataContract] + public class App + { + [DataMember(Name = "id")] + public string Id { get; set; } + + [DataMember(Name = "name")] + public string Name { get; set; } + + [DataMember(Name = "url")] + public string Url { get; set; } + } + + [DataMember(Name = "events")] + public TwitterMessageEvent[] Events { get; set; } + + [DataMember(Name = "next_cursor", IsRequired = false)] + public string? NextCursor { get; set; } + } + + [DataContract] + public class TwitterMessageEventSingle + { + [DataMember(Name = "event")] + public TwitterMessageEvent Event { get; set; } + } +} diff --git a/OpenTween/Api/DataModel/TwitterStreamMessage.cs b/OpenTween/Api/DataModel/TwitterStreamMessage.cs index f2b46a95a..32263f623 100644 --- a/OpenTween/Api/DataModel/TwitterStreamMessage.cs +++ b/OpenTween/Api/DataModel/TwitterStreamMessage.cs @@ -20,6 +20,7 @@ // Boston, MA 02110-1301, USA. #nullable enable annotations +#pragma warning disable SA1649 using System.Runtime.Serialization; diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 1b4e1c9a5..f05643a16 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -44,7 +44,7 @@ namespace OpenTween { - internal class MyApplication + internal class ApplicationEvents { public static readonly CultureInfo[] SupportedUICulture = new[] { diff --git a/OpenTween/Growl.cs b/OpenTween/GrowlHelper.cs similarity index 100% rename from OpenTween/Growl.cs rename to OpenTween/GrowlHelper.cs diff --git a/OpenTween/WebBrowserController.cs b/OpenTween/InternetSecurityManager.cs similarity index 99% rename from OpenTween/WebBrowserController.cs rename to OpenTween/InternetSecurityManager.cs index bbe35ea1a..0a3a97aec 100644 --- a/OpenTween/WebBrowserController.cs +++ b/OpenTween/InternetSecurityManager.cs @@ -39,6 +39,191 @@ namespace OpenTween { + public class InternetSecurityManager : WebBrowserAPI.IServiceProvider, WebBrowserAPI.IInternetSecurityManager + { + #region "HRESULT" + private enum HRESULT + { + S_OK = 0x0, + S_FALSE = 0x1, + E_NOTIMPL = unchecked((int)0x80004001), + E_NOINTERFACE = unchecked((int)0x80004002), + } + #endregion + + [Flags] + public enum POLICY + { + ALLOW_ACTIVEX = 0x1, + ALLOW_SCRIPT = 0x2, + } + + private readonly object ocx = new object(); + private readonly WebBrowserAPI.IServiceProvider ocxServiceProvider; + private readonly IntPtr profferServicePtr = new IntPtr(); + private readonly WebBrowserAPI.IProfferService profferService = null!; + + public POLICY SecurityPolicy { get; set; } = 0; + + public InternetSecurityManager(WebBrowser webBrowser) + { + // ActiveXコントロール取得 + webBrowser.Url = new Uri("about:blank"); // ActiveXを初期化する + + do + { + Thread.Sleep(100); + Application.DoEvents(); + } + while (webBrowser.ReadyState != WebBrowserReadyState.Complete); + + this.ocx = webBrowser.ActiveXInstance; + + // IServiceProvider.QueryService() を使って IProfferService を取得 + this.ocxServiceProvider = (WebBrowserAPI.IServiceProvider)this.ocx; + + try + { + this.ocxServiceProvider.QueryService( + ref WebBrowserAPI.SID_SProfferService, + ref WebBrowserAPI.IID_IProfferService, + out this.profferServicePtr); + } + catch (SEHException ex) + { + MyCommon.TraceOut(ex, "ocxServiceProvider.QueryService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine); + return; + } + catch (ExternalException ex) + { + MyCommon.TraceOut(ex, "ocxServiceProvider.QueryService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine); + return; + } + + this.profferService = (WebBrowserAPI.IProfferService)Marshal.GetObjectForIUnknown(this.profferServicePtr); + + // IProfferService.ProfferService() を使って + // 自分を IInternetSecurityManager として提供 + try + { + this.profferService.ProfferService( + ref WebBrowserAPI.IID_IInternetSecurityManager, this, out var cookie); + } + catch (SEHException ex) + { + MyCommon.TraceOut(ex, "IProfferSerive.ProfferService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine); + return; + } + catch (ExternalException ex) + { + MyCommon.TraceOut(ex, "IProfferSerive.ProfferService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine); + return; + } + } + + int WebBrowserAPI.IServiceProvider.QueryService( + ref Guid guidService, + ref Guid riid, + out IntPtr ppvObject) + { + ppvObject = IntPtr.Zero; + if (guidService.CompareTo( + WebBrowserAPI.IID_IInternetSecurityManager) == 0) + { + // 自分から IID_IInternetSecurityManager を + // QueryInterface して返す + var punk = Marshal.GetIUnknownForObject(this); + return Marshal.QueryInterface(punk, ref riid, out ppvObject); + } + return (int)HRESULT.E_NOINTERFACE; + } + + int WebBrowserAPI.IInternetSecurityManager.GetSecurityId(string pwszUrl, byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved) + => WebBrowserAPI.INET_E_DEFAULT_ACTION; + + int WebBrowserAPI.IInternetSecurityManager.GetSecuritySite(out WebBrowserAPI.IInternetSecurityMgrSite? pSite) + { + pSite = null; + return WebBrowserAPI.INET_E_DEFAULT_ACTION; + } + + int WebBrowserAPI.IInternetSecurityManager.GetZoneMappings(int dwZone, ref IEnumString? ppenumstring, int dwFlags) + { + ppenumstring = null; + return WebBrowserAPI.INET_E_DEFAULT_ACTION; + } + + int WebBrowserAPI.IInternetSecurityManager.MapUrlToZone(string pwszUrl, out int pdwZone, int dwFlags) + { + pdwZone = 0; + if (pwszUrl == "about:blank") return WebBrowserAPI.INET_E_DEFAULT_ACTION; + try + { + var urlStr = MyCommon.IDNEncode(pwszUrl); + if (urlStr == null) return WebBrowserAPI.URLPOLICY_DISALLOW; + var url = new Uri(urlStr); + if (url.Scheme == "data") + { + return WebBrowserAPI.URLPOLICY_DISALLOW; + } + } + catch (Exception) + { + return WebBrowserAPI.URLPOLICY_DISALLOW; + } + return WebBrowserAPI.INET_E_DEFAULT_ACTION; + } + + private const byte URLPOLICY_ALLOW = 0; + + int WebBrowserAPI.IInternetSecurityManager.ProcessUrlAction(string pwszUrl, int dwAction, out byte pPolicy, int cbPolicy, byte pContext, int cbContext, int dwFlags, int dwReserved) + { + pPolicy = URLPOLICY_ALLOW; + // スクリプト実行状態かを検査しポリシー設定 + if (WebBrowserAPI.URLACTION_SCRIPT_MIN <= dwAction & + dwAction <= WebBrowserAPI.URLACTION_SCRIPT_MAX) + { + // スクリプト実行状態 + if ((this.SecurityPolicy & POLICY.ALLOW_SCRIPT) == POLICY.ALLOW_SCRIPT) + { + pPolicy = WebBrowserAPI.URLPOLICY_ALLOW; + } + else + { + pPolicy = WebBrowserAPI.URLPOLICY_DISALLOW; + } + if (Regex.IsMatch(pwszUrl, @"^https?://((api\.)?twitter\.com/|([a-zA-Z0-9]+\.)?twimg\.com/)")) pPolicy = WebBrowserAPI.URLPOLICY_ALLOW; + return (int)HRESULT.S_OK; + } + // ActiveX実行状態かを検査しポリシー設定 + if (WebBrowserAPI.URLACTION_ACTIVEX_MIN <= dwAction & + dwAction <= WebBrowserAPI.URLACTION_ACTIVEX_MAX) + { + // ActiveX実行状態 + if ((this.SecurityPolicy & POLICY.ALLOW_ACTIVEX) == POLICY.ALLOW_ACTIVEX) + { + pPolicy = WebBrowserAPI.URLPOLICY_ALLOW; + } + else + { + pPolicy = WebBrowserAPI.URLPOLICY_DISALLOW; + } + return (int)HRESULT.S_OK; + } + // 他のものについてはデフォルト処理 + return WebBrowserAPI.INET_E_DEFAULT_ACTION; + } + + int WebBrowserAPI.IInternetSecurityManager.QueryCustomPolicy(string pwszUrl, ref Guid guidKey, byte ppPolicy, int pcbPolicy, byte pContext, int cbContext, int dwReserved) + => WebBrowserAPI.INET_E_DEFAULT_ACTION; + + int WebBrowserAPI.IInternetSecurityManager.SetSecuritySite(WebBrowserAPI.IInternetSecurityMgrSite pSite) + => WebBrowserAPI.INET_E_DEFAULT_ACTION; + + int WebBrowserAPI.IInternetSecurityManager.SetZoneMapping(int dwZone, string lpszPattern, int dwFlags) + => WebBrowserAPI.INET_E_DEFAULT_ACTION; + } + #region "WebBrowserAPI" internal static class WebBrowserAPI { @@ -259,189 +444,4 @@ public interface IInternetSecurityManager } } #endregion - - public class InternetSecurityManager : WebBrowserAPI.IServiceProvider, WebBrowserAPI.IInternetSecurityManager - { - #region "HRESULT" - private enum HRESULT - { - S_OK = 0x0, - S_FALSE = 0x1, - E_NOTIMPL = unchecked((int)0x80004001), - E_NOINTERFACE = unchecked((int)0x80004002), - } - #endregion - - [Flags] - public enum POLICY - { - ALLOW_ACTIVEX = 0x1, - ALLOW_SCRIPT = 0x2, - } - - private readonly object ocx = new object(); - private readonly WebBrowserAPI.IServiceProvider ocxServiceProvider; - private readonly IntPtr profferServicePtr = new IntPtr(); - private readonly WebBrowserAPI.IProfferService profferService = null!; - - public POLICY SecurityPolicy { get; set; } = 0; - - public InternetSecurityManager(WebBrowser webBrowser) - { - // ActiveXコントロール取得 - webBrowser.Url = new Uri("about:blank"); // ActiveXを初期化する - - do - { - Thread.Sleep(100); - Application.DoEvents(); - } - while (webBrowser.ReadyState != WebBrowserReadyState.Complete); - - this.ocx = webBrowser.ActiveXInstance; - - // IServiceProvider.QueryService() を使って IProfferService を取得 - this.ocxServiceProvider = (WebBrowserAPI.IServiceProvider)this.ocx; - - try - { - this.ocxServiceProvider.QueryService( - ref WebBrowserAPI.SID_SProfferService, - ref WebBrowserAPI.IID_IProfferService, - out this.profferServicePtr); - } - catch (SEHException ex) - { - MyCommon.TraceOut(ex, "ocxServiceProvider.QueryService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine); - return; - } - catch (ExternalException ex) - { - MyCommon.TraceOut(ex, "ocxServiceProvider.QueryService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine); - return; - } - - this.profferService = (WebBrowserAPI.IProfferService)Marshal.GetObjectForIUnknown(this.profferServicePtr); - - // IProfferService.ProfferService() を使って - // 自分を IInternetSecurityManager として提供 - try - { - this.profferService.ProfferService( - ref WebBrowserAPI.IID_IInternetSecurityManager, this, out var cookie); - } - catch (SEHException ex) - { - MyCommon.TraceOut(ex, "IProfferSerive.ProfferService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine); - return; - } - catch (ExternalException ex) - { - MyCommon.TraceOut(ex, "IProfferSerive.ProfferService() HRESULT:" + ex.ErrorCode.ToString("X8") + Environment.NewLine); - return; - } - } - - int WebBrowserAPI.IServiceProvider.QueryService( - ref Guid guidService, - ref Guid riid, - out IntPtr ppvObject) - { - ppvObject = IntPtr.Zero; - if (guidService.CompareTo( - WebBrowserAPI.IID_IInternetSecurityManager) == 0) - { - // 自分から IID_IInternetSecurityManager を - // QueryInterface して返す - var punk = Marshal.GetIUnknownForObject(this); - return Marshal.QueryInterface(punk, ref riid, out ppvObject); - } - return (int)HRESULT.E_NOINTERFACE; - } - - int WebBrowserAPI.IInternetSecurityManager.GetSecurityId(string pwszUrl, byte[] pbSecurityId, ref uint pcbSecurityId, uint dwReserved) - => WebBrowserAPI.INET_E_DEFAULT_ACTION; - - int WebBrowserAPI.IInternetSecurityManager.GetSecuritySite(out WebBrowserAPI.IInternetSecurityMgrSite? pSite) - { - pSite = null; - return WebBrowserAPI.INET_E_DEFAULT_ACTION; - } - - int WebBrowserAPI.IInternetSecurityManager.GetZoneMappings(int dwZone, ref IEnumString? ppenumstring, int dwFlags) - { - ppenumstring = null; - return WebBrowserAPI.INET_E_DEFAULT_ACTION; - } - - int WebBrowserAPI.IInternetSecurityManager.MapUrlToZone(string pwszUrl, out int pdwZone, int dwFlags) - { - pdwZone = 0; - if (pwszUrl == "about:blank") return WebBrowserAPI.INET_E_DEFAULT_ACTION; - try - { - var urlStr = MyCommon.IDNEncode(pwszUrl); - if (urlStr == null) return WebBrowserAPI.URLPOLICY_DISALLOW; - var url = new Uri(urlStr); - if (url.Scheme == "data") - { - return WebBrowserAPI.URLPOLICY_DISALLOW; - } - } - catch (Exception) - { - return WebBrowserAPI.URLPOLICY_DISALLOW; - } - return WebBrowserAPI.INET_E_DEFAULT_ACTION; - } - - private const byte URLPOLICY_ALLOW = 0; - - int WebBrowserAPI.IInternetSecurityManager.ProcessUrlAction(string pwszUrl, int dwAction, out byte pPolicy, int cbPolicy, byte pContext, int cbContext, int dwFlags, int dwReserved) - { - pPolicy = URLPOLICY_ALLOW; - // スクリプト実行状態かを検査しポリシー設定 - if (WebBrowserAPI.URLACTION_SCRIPT_MIN <= dwAction & - dwAction <= WebBrowserAPI.URLACTION_SCRIPT_MAX) - { - // スクリプト実行状態 - if ((this.SecurityPolicy & POLICY.ALLOW_SCRIPT) == POLICY.ALLOW_SCRIPT) - { - pPolicy = WebBrowserAPI.URLPOLICY_ALLOW; - } - else - { - pPolicy = WebBrowserAPI.URLPOLICY_DISALLOW; - } - if (Regex.IsMatch(pwszUrl, @"^https?://((api\.)?twitter\.com/|([a-zA-Z0-9]+\.)?twimg\.com/)")) pPolicy = WebBrowserAPI.URLPOLICY_ALLOW; - return (int)HRESULT.S_OK; - } - // ActiveX実行状態かを検査しポリシー設定 - if (WebBrowserAPI.URLACTION_ACTIVEX_MIN <= dwAction & - dwAction <= WebBrowserAPI.URLACTION_ACTIVEX_MAX) - { - // ActiveX実行状態 - if ((this.SecurityPolicy & POLICY.ALLOW_ACTIVEX) == POLICY.ALLOW_ACTIVEX) - { - pPolicy = WebBrowserAPI.URLPOLICY_ALLOW; - } - else - { - pPolicy = WebBrowserAPI.URLPOLICY_DISALLOW; - } - return (int)HRESULT.S_OK; - } - // 他のものについてはデフォルト処理 - return WebBrowserAPI.INET_E_DEFAULT_ACTION; - } - - int WebBrowserAPI.IInternetSecurityManager.QueryCustomPolicy(string pwszUrl, ref Guid guidKey, byte ppPolicy, int pcbPolicy, byte pContext, int cbContext, int dwReserved) - => WebBrowserAPI.INET_E_DEFAULT_ACTION; - - int WebBrowserAPI.IInternetSecurityManager.SetSecuritySite(WebBrowserAPI.IInternetSecurityMgrSite pSite) - => WebBrowserAPI.INET_E_DEFAULT_ACTION; - - int WebBrowserAPI.IInternetSecurityManager.SetZoneMapping(int dwZone, string lpszPattern, int dwFlags) - => WebBrowserAPI.INET_E_DEFAULT_ACTION; - } } diff --git a/OpenTween/NullableAttributes.cs b/OpenTween/NullableAttributes.cs index da108132a..6470366d6 100644 --- a/OpenTween/NullableAttributes.cs +++ b/OpenTween/NullableAttributes.cs @@ -20,6 +20,7 @@ // Boston, MA 02110-1301, USA. #nullable enable +#pragma warning disable SA1649 namespace System.Diagnostics.CodeAnalysis { diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 1172309bf..16fd1c0d9 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -38,7 +38,7 @@ false - OpenTween.MyApplication + OpenTween.ApplicationEvents Resources\4b.ico @@ -73,11 +73,13 @@ + + Code @@ -386,7 +388,7 @@ UpdateDialog.cs - + Form @@ -458,7 +460,7 @@ - + diff --git a/OpenTween/ReaderWriterLockTransaction.cs b/OpenTween/ReaderWriterLockTransaction.cs index f3e5ba0bf..d6b1a30a2 100644 --- a/OpenTween/ReaderWriterLockTransaction.cs +++ b/OpenTween/ReaderWriterLockTransaction.cs @@ -20,6 +20,7 @@ // Boston, MA 02110-1301, USA. #nullable enable +#pragma warning disable SA1649 using System; using System.Collections.Generic; diff --git a/OpenTween/Thumbnail/MapThumb.cs b/OpenTween/Thumbnail/MapThumb.cs index 764cac14f..810248dff 100644 --- a/OpenTween/Thumbnail/MapThumb.cs +++ b/OpenTween/Thumbnail/MapThumb.cs @@ -32,19 +32,6 @@ namespace OpenTween.Thumbnail { - public class GlobalLocation - { - public double Latitude { get; set; } - - public double Longitude { get; set; } - } - - public enum MapProvider - { - OpenStreetMap, - GoogleMaps, - } - public abstract class MapThumb { public abstract Task GetThumbnailInfoAsync(PostClass.StatusGeo geo); @@ -69,4 +56,17 @@ public static MapThumb GetDefaultInstance() return MapThumb.defaultInstance; } } + + public class GlobalLocation + { + public double Latitude { get; set; } + + public double Longitude { get; set; } + } + + public enum MapProvider + { + OpenStreetMap, + GoogleMaps, + } } From 4dc65d8fd10b11c3a717735d545255eb6f129fda Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 08:49:56 +0900 Subject: [PATCH 111/402] =?UTF-8?q?=E3=80=8C=E8=AD=A6=E5=91=8A=E3=82=92?= =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=A8=E3=81=97=E3=81=A6=E6=89=B1?= =?UTF-8?q?=E3=81=86=E3=80=8D=E3=82=92=E6=9C=89=E5=8A=B9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/OpenTween.Tests.csproj | 1 + OpenTween/OpenTween.csproj | 1 + 2 files changed, 2 insertions(+) diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index 36821621d..bfbd8d071 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -6,6 +6,7 @@ 8.0 enable true + True diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 16fd1c0d9..1b97d7a25 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -25,6 +25,7 @@ Auto false OpenTween.ruleset + true pdbonly From 801d86a6acfbb3576083fe2a469d97d1dca2085c Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 21:01:13 +0900 Subject: [PATCH 112/402] =?UTF-8?q?ChangeLog=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit e1907819b7beb9b1ca03dbf077ad87cc446eea91 の変更を反映 --- OpenTween/Resources/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 8a7e6b2e8..e46e07b61 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Ver 2.5.1-dev(2022/xx/xx) * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) + * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました From ae03bdf82bd4469717d89a7bbce54b4e5d303185 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 28 Feb 2022 22:44:38 +0900 Subject: [PATCH 113/402] =?UTF-8?q?InnerStorageTabType=E3=81=AB=E5=90=AB?= =?UTF-8?q?=E3=81=BE=E3=82=8C=E3=82=8B=E7=99=BA=E8=A8=80=E3=81=AEIsOwl?= =?UTF-8?q?=E3=81=AE=E6=9B=B4=E6=96=B0=E3=81=AB=E5=AF=BE=E5=BF=9C=20(thx?= =?UTF-8?q?=20@Hawklaver!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/TabInformationTest.cs | 63 ++++++++++++++++++++ OpenTween/Models/TabInformations.cs | 8 ++- OpenTween/Resources/ChangeLog.txt | 1 + 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/OpenTween.Tests/Models/TabInformationTest.cs b/OpenTween.Tests/Models/TabInformationTest.cs index 7f1f834d5..ae4dff643 100644 --- a/OpenTween.Tests/Models/TabInformationTest.cs +++ b/OpenTween.Tests/Models/TabInformationTest.cs @@ -830,6 +830,69 @@ public void FilterAll_ExcludeReplyFilterTest() Assert.True(this.tabinfo[200L]!.IsExcludeReply); } + [Fact] + public void RefreshOwl_HomeTabTest() + { + var post = new PostClass + { + StatusId = 100L, + ScreenName = "aaa", + UserId = 123L, + IsOwl = true, + }; + this.tabinfo.AddPost(post); + this.tabinfo.DistributePosts(); + this.tabinfo.SubmitUpdate(); + + var followerIds = new HashSet { 123L }; + this.tabinfo.RefreshOwl(followerIds); + + Assert.False(post.IsOwl); + } + + [Fact] + public void RefreshOwl_InnerStoregeTabTest() + { + var tab = new PublicSearchTabModel("search"); + this.tabinfo.AddTab(tab); + + var post = new PostClass + { + StatusId = 100L, + ScreenName = "aaa", + UserId = 123L, + IsOwl = true, + }; + tab.AddPostQueue(post); + this.tabinfo.DistributePosts(); + this.tabinfo.SubmitUpdate(); + + var followerIds = new HashSet { 123L }; + this.tabinfo.RefreshOwl(followerIds); + + Assert.False(post.IsOwl); + } + + [Fact] + public void RefreshOwl_UnfollowedTest() + { + var post = new PostClass + { + StatusId = 100L, + ScreenName = "aaa", + UserId = 123L, + IsOwl = false, + }; + this.tabinfo.AddPost(post); + this.tabinfo.DistributePosts(); + this.tabinfo.SubmitUpdate(); + + var followerIds = new HashSet { 456L }; + this.tabinfo.RefreshOwl(followerIds); + + Assert.True(post.IsOwl); + } + private class TestPostFilterRule : PostFilterRule { public static PostFilterRule Create(Func filterDelegate) diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index 17946c35a..480d6caf1 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -808,9 +808,13 @@ public void RefreshOwl(ISet follower) { lock (this.lockObj) { + var allPosts = this.GetTabsInnerStorageType() + .SelectMany(x => x.Posts.Values) + .Concat(this.Posts.Values); + if (follower.Count > 0) { - foreach (var post in this.Posts.Values) + foreach (var post in allPosts) { if (post.IsMe) { @@ -824,7 +828,7 @@ public void RefreshOwl(ISet follower) } else { - foreach (var post in this.Posts.Values) + foreach (var post in allPosts) { post.IsOwl = false; } diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index e46e07b61..3a34580fa 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -3,6 +3,7 @@ ==== Ver 2.5.1-dev(2022/xx/xx) * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) + * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました From 460fdbc56ca405dc8216b1b17fbed83a99450407 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 1 Mar 2022 00:05:21 +0900 Subject: [PATCH 114/402] =?UTF-8?q?`/warnaserror`=20=E3=82=AA=E3=83=97?= =?UTF-8?q?=E3=82=B7=E3=83=A7=E3=83=B3=E3=82=92AppVeyor=E3=81=A7=E3=81=AE?= =?UTF-8?q?=E3=83=93=E3=83=AB=E3=83=89=E6=99=82=E3=81=AE=E3=81=BF=E6=9C=89?= =?UTF-8?q?=E5=8A=B9=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/OpenTween.Tests.csproj | 1 - OpenTween/OpenTween.csproj | 1 - msbuild.rsp | 3 +++ 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 msbuild.rsp diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index bfbd8d071..36821621d 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -6,7 +6,6 @@ 8.0 enable true - True diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 1b97d7a25..16fd1c0d9 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -25,7 +25,6 @@ Auto false OpenTween.ruleset - true pdbonly diff --git a/msbuild.rsp b/msbuild.rsp new file mode 100644 index 000000000..c4dbaecb1 --- /dev/null +++ b/msbuild.rsp @@ -0,0 +1,3 @@ +# MSBuild response file for AppVeyor build + +/warnaserror From 708b66ba9a9eba2896273cbc40f613b5716f3aac Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 19 Mar 2022 02:13:56 +0900 Subject: [PATCH 115/402] =?UTF-8?q?AppVeyor=E3=81=A7=E3=81=AE=E3=83=93?= =?UTF-8?q?=E3=83=AB=E3=83=89=E3=81=AB=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= =?UTF-8?q?=E7=92=B0=E5=A2=83=E3=82=92VS2022=E3=81=AB=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 47dd0f982..bf01707fb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ version: 2.5.0.{build} -os: Visual Studio 2019 +os: Visual Studio 2022 environment: matrix: @@ -62,7 +62,7 @@ after_test: - ./node_modules/.bin/codecov -f coverage.xml - ps: | - $env:PATH = $env:PATH + ';C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\bin\Roslyn\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\' + $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\Roslyn\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\' $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\' $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\' $assemblyInfo = '.\OpenTween\Properties\AssemblyInfo.cs' From cb1641e11c4134f0e3d362ad354d61c4988ab0ff Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 19 Mar 2022 03:34:13 +0900 Subject: [PATCH 116/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E3=82=B3=E3=83=B3=E3=83=86=E3=82=AD=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=83=A1=E3=83=8B=E3=83=A5=E3=83=BC=E5=86=85=E3=81=AB=E3=81=82?= =?UTF-8?q?=E3=82=8B=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=AB=E9=96=A2?= =?UTF-8?q?=E3=81=99=E3=82=8B=E9=A0=85=E7=9B=AE=E3=82=92=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.Designer.cs | 300 +++++++++++++++++------------- OpenTween/Tween.cs | 73 +++----- OpenTween/Tween.en.resx | 68 +++---- OpenTween/Tween.resx | 156 +++++++++------- 5 files changed, 315 insertions(+), 283 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 3a34580fa..06419120c 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Ver 2.5.1-dev(2022/xx/xx) * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) + * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index a5a76aa68..0523437d9 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -104,24 +104,26 @@ private void InitializeComponent() this.FavoriteRetweetUnofficialMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.UnFavOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripSeparator38 = new System.Windows.Forms.ToolStripSeparator(); - this.ShowProfMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShowRelatedStatusesMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); - this.ShowUserTimelineToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ShowRetweeterProfMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ShowRetweeterUserTimelineToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorShowProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorShowUserTimelineMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorListManageMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorOpenInBrowserMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorOpenFavoritesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByShowProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByShowUserTimelineMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByOpenInBrowserMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.OpenHomeOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.OpenFavOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenStatusOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenRepSourceOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenUrlOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.OpenRterHomeMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenUserSpecifiedUrlMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CreateRuleOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CreateTabRuleOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CreateIdRuleOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CreateSourceRuleOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ListManageMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripSeparator26 = new System.Windows.Forms.ToolStripSeparator(); this.ChangeReadOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ReadOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -202,10 +204,8 @@ private void InitializeComponent() this.JumpUnreadMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator(); this.ToolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator(); - this.ListManageUserContextToolStripMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); this.OpenURLMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.IDRuleMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.MoveToRTHomeMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.TabMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenUserSpecifiedUrlMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); this.DeleteStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -241,14 +241,18 @@ private void InitializeComponent() this.FavoriteRetweetUnofficialContextMenu = new System.Windows.Forms.ToolStripMenuItem(); this.FavRemoveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); - this.ShowProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShowRelatedStatusesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ShowRetweeterProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.ShowRetweeterUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorShowProfileContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorListManageContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorOpenInBrowserContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.AuthorOpenFavoritesContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByShowProfileContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByOpenInBrowserContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripMenuItem6 = new System.Windows.Forms.ToolStripMenuItem(); - this.MoveToHomeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.MoveToFavToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolTip1 = new System.Windows.Forms.ToolTip(this.components); this.TimerRefreshIcon = new System.Windows.Forms.Timer(this.components); this.PostStateImageList = new System.Windows.Forms.ImageList(this.components); @@ -917,14 +921,11 @@ private void InitializeComponent() this.FavoriteRetweetUnofficialMenuItem, this.UnFavOpMenuItem, this.ToolStripSeparator38, - this.ShowProfMenuItem, this.ShowRelatedStatusesMenuItem2, - this.ShowUserTimelineToolStripMenuItem, + this.AuthorMenuItem, + this.RetweetedByMenuItem, this.OpenOpMenuItem, this.CreateRuleOpMenuItem, - this.ListManageMenuItem, - this.ShowRetweeterProfMenuItem, - this.ShowRetweeterUserTimelineToolStripMenuItem, this.ToolStripSeparator26, this.ChangeReadOpMenuItem, this.JumpReadOpMenuItem, @@ -1007,61 +1008,90 @@ private void InitializeComponent() this.ToolStripSeparator38.Name = "ToolStripSeparator38"; resources.ApplyResources(this.ToolStripSeparator38, "ToolStripSeparator38"); // - // ShowProfMenuItem - // - this.ShowProfMenuItem.Name = "ShowProfMenuItem"; - resources.ApplyResources(this.ShowProfMenuItem, "ShowProfMenuItem"); - this.ShowProfMenuItem.Click += new System.EventHandler(this.ShowProfileMenuItem_Click); - // // ShowRelatedStatusesMenuItem2 // this.ShowRelatedStatusesMenuItem2.Name = "ShowRelatedStatusesMenuItem2"; resources.ApplyResources(this.ShowRelatedStatusesMenuItem2, "ShowRelatedStatusesMenuItem2"); this.ShowRelatedStatusesMenuItem2.Click += new System.EventHandler(this.ShowRelatedStatusesMenuItem_Click); // - // ShowUserTimelineToolStripMenuItem + // AuthorMenuItem + // + this.AuthorMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.AuthorShowProfileMenuItem, + this.AuthorShowUserTimelineMenuItem, + this.AuthorListManageMenuItem, + this.AuthorOpenInBrowserMenuItem, + this.AuthorOpenFavoritesMenuItem}); + this.AuthorMenuItem.Name = "AuthorMenuItem"; + resources.ApplyResources(this.AuthorMenuItem, "AuthorMenuItem"); + // + // AuthorShowProfileMenuItem + // + this.AuthorShowProfileMenuItem.Name = "AuthorShowProfileMenuItem"; + resources.ApplyResources(this.AuthorShowProfileMenuItem, "AuthorShowProfileMenuItem"); + this.AuthorShowProfileMenuItem.Click += new System.EventHandler(this.AuthorShowProfileMenuItem_Click); + // + // AuthorShowUserTimelineMenuItem + // + this.AuthorShowUserTimelineMenuItem.Name = "AuthorShowUserTimelineMenuItem"; + resources.ApplyResources(this.AuthorShowUserTimelineMenuItem, "AuthorShowUserTimelineMenuItem"); + this.AuthorShowUserTimelineMenuItem.Click += new System.EventHandler(this.AuthorShowUserTimelineMenuItem_Click); + // + // AuthorListManageMenuItem + // + this.AuthorListManageMenuItem.Name = "AuthorListManageMenuItem"; + resources.ApplyResources(this.AuthorListManageMenuItem, "AuthorListManageMenuItem"); + this.AuthorListManageMenuItem.Click += new System.EventHandler(this.AuthorListManageMenuItem_Click); + // + // AuthorOpenInBrowserMenuItem + // + this.AuthorOpenInBrowserMenuItem.Name = "AuthorOpenInBrowserMenuItem"; + resources.ApplyResources(this.AuthorOpenInBrowserMenuItem, "AuthorOpenInBrowserMenuItem"); + this.AuthorOpenInBrowserMenuItem.Click += new System.EventHandler(this.AuthorOpenInBrowserMenuItem_Click); + // + // AuthorOpenFavoritesMenuItem // - this.ShowUserTimelineToolStripMenuItem.Name = "ShowUserTimelineToolStripMenuItem"; - resources.ApplyResources(this.ShowUserTimelineToolStripMenuItem, "ShowUserTimelineToolStripMenuItem"); - this.ShowUserTimelineToolStripMenuItem.Click += new System.EventHandler(this.ShowUserTimelineToolStripMenuItem_Click); + this.AuthorOpenFavoritesMenuItem.Name = "AuthorOpenFavoritesMenuItem"; + resources.ApplyResources(this.AuthorOpenFavoritesMenuItem, "AuthorOpenFavoritesMenuItem"); + this.AuthorOpenFavoritesMenuItem.Click += new System.EventHandler(this.AuthorOpenFavoritesMenuItem_Click); // - // ShowRetweeterProfMenuItem + // RetweetedByMenuItem // - this.ShowRetweeterProfMenuItem.Name = "ShowRetweeterProfMenuItem"; - resources.ApplyResources(this.ShowRetweeterProfMenuItem, "ShowRetweeterProfMenuItem"); - this.ShowRetweeterProfMenuItem.Click += new System.EventHandler(this.ShowRetweeterProfileMenuItem_Click); + this.RetweetedByMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.RetweetedByShowProfileMenuItem, + this.RetweetedByShowUserTimelineMenuItem, + this.RetweetedByOpenInBrowserMenuItem}); + this.RetweetedByMenuItem.Name = "RetweetedByMenuItem"; + resources.ApplyResources(this.RetweetedByMenuItem, "RetweetedByMenuItem"); // - // ShowRetweeterUserTimelineToolStripMenuItem + // RetweetedByShowProfileMenuItem // - this.ShowRetweeterUserTimelineToolStripMenuItem.Name = "ShowRetweeterUserTimelineToolStripMenuItem"; - resources.ApplyResources(this.ShowRetweeterUserTimelineToolStripMenuItem, "ShowRetweeterUserTimelineToolStripMenuItem"); - this.ShowRetweeterUserTimelineToolStripMenuItem.Click += new System.EventHandler(this.ShowRetweeterUserTimelineToolStripMenuItem_Click); + this.RetweetedByShowProfileMenuItem.Name = "RetweetedByShowProfileMenuItem"; + resources.ApplyResources(this.RetweetedByShowProfileMenuItem, "RetweetedByShowProfileMenuItem"); + this.RetweetedByShowProfileMenuItem.Click += new System.EventHandler(this.RetweetedByShowProfileMenuItem_Click); + // + // RetweetedByShowUserTimelineMenuItem + // + this.RetweetedByShowUserTimelineMenuItem.Name = "RetweetedByShowUserTimelineMenuItem"; + resources.ApplyResources(this.RetweetedByShowUserTimelineMenuItem, "RetweetedByShowUserTimelineMenuItem"); + this.RetweetedByShowUserTimelineMenuItem.Click += new System.EventHandler(this.RetweetedByShowUserTimelineMenuItem_Click); + // + // RetweetedByOpenInBrowserMenuItem + // + this.RetweetedByOpenInBrowserMenuItem.Name = "RetweetedByOpenInBrowserMenuItem"; + resources.ApplyResources(this.RetweetedByOpenInBrowserMenuItem, "RetweetedByOpenInBrowserMenuItem"); + this.RetweetedByOpenInBrowserMenuItem.Click += new System.EventHandler(this.RetweetedByOpenInBrowserMenuItem_Click); // // OpenOpMenuItem // this.OpenOpMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.OpenHomeOpMenuItem, - this.OpenFavOpMenuItem, this.OpenStatusOpMenuItem, this.OpenRepSourceOpMenuItem, this.OpenUrlOpMenuItem, - this.OpenRterHomeMenuItem, this.OpenUserSpecifiedUrlMenuItem}); this.OpenOpMenuItem.Name = "OpenOpMenuItem"; resources.ApplyResources(this.OpenOpMenuItem, "OpenOpMenuItem"); // - // OpenHomeOpMenuItem - // - this.OpenHomeOpMenuItem.Name = "OpenHomeOpMenuItem"; - resources.ApplyResources(this.OpenHomeOpMenuItem, "OpenHomeOpMenuItem"); - this.OpenHomeOpMenuItem.Click += new System.EventHandler(this.MoveToHomeToolStripMenuItem_Click); - // - // OpenFavOpMenuItem - // - this.OpenFavOpMenuItem.Name = "OpenFavOpMenuItem"; - resources.ApplyResources(this.OpenFavOpMenuItem, "OpenFavOpMenuItem"); - this.OpenFavOpMenuItem.Click += new System.EventHandler(this.MoveToFavToolStripMenuItem_Click); - // // OpenStatusOpMenuItem // this.OpenStatusOpMenuItem.Name = "OpenStatusOpMenuItem"; @@ -1080,12 +1110,6 @@ private void InitializeComponent() resources.ApplyResources(this.OpenUrlOpMenuItem, "OpenUrlOpMenuItem"); this.OpenUrlOpMenuItem.Click += new System.EventHandler(this.OpenURLMenuItem_Click); // - // OpenRterHomeMenuItem - // - this.OpenRterHomeMenuItem.Name = "OpenRterHomeMenuItem"; - resources.ApplyResources(this.OpenRterHomeMenuItem, "OpenRterHomeMenuItem"); - this.OpenRterHomeMenuItem.Click += new System.EventHandler(this.MoveToRTHomeMenuItem_Click); - // // OpenUserSpecifiedUrlMenuItem // this.OpenUserSpecifiedUrlMenuItem.Name = "OpenUserSpecifiedUrlMenuItem"; @@ -1119,12 +1143,6 @@ private void InitializeComponent() resources.ApplyResources(this.CreateSourceRuleOpMenuItem, "CreateSourceRuleOpMenuItem"); this.CreateSourceRuleOpMenuItem.Click += new System.EventHandler(this.SourceRuleMenuItem_Click); // - // ListManageMenuItem - // - this.ListManageMenuItem.Name = "ListManageMenuItem"; - resources.ApplyResources(this.ListManageMenuItem, "ListManageMenuItem"); - this.ListManageMenuItem.Click += new System.EventHandler(this.ListManageUserContextToolStripMenuItem_Click); - // // ToolStripSeparator26 // this.ToolStripSeparator26.Name = "ToolStripSeparator26"; @@ -1672,12 +1690,6 @@ private void InitializeComponent() this.ToolStripSeparator10.Name = "ToolStripSeparator10"; resources.ApplyResources(this.ToolStripSeparator10, "ToolStripSeparator10"); // - // ListManageUserContextToolStripMenuItem2 - // - this.ListManageUserContextToolStripMenuItem2.Name = "ListManageUserContextToolStripMenuItem2"; - resources.ApplyResources(this.ListManageUserContextToolStripMenuItem2, "ListManageUserContextToolStripMenuItem2"); - this.ListManageUserContextToolStripMenuItem2.Click += new System.EventHandler(this.ListManageUserContextToolStripMenuItem_Click); - // // OpenURLMenuItem // this.OpenURLMenuItem.Name = "OpenURLMenuItem"; @@ -1690,12 +1702,6 @@ private void InitializeComponent() resources.ApplyResources(this.IDRuleMenuItem, "IDRuleMenuItem"); this.IDRuleMenuItem.Click += new System.EventHandler(this.IDRuleMenuItem_Click); // - // MoveToRTHomeMenuItem - // - this.MoveToRTHomeMenuItem.Name = "MoveToRTHomeMenuItem"; - resources.ApplyResources(this.MoveToRTHomeMenuItem, "MoveToRTHomeMenuItem"); - this.MoveToRTHomeMenuItem.Click += new System.EventHandler(this.MoveToRTHomeMenuItem_Click); - // // TabMenuItem // this.TabMenuItem.Name = "TabMenuItem"; @@ -1853,14 +1859,11 @@ private void InitializeComponent() this.FavoriteRetweetUnofficialContextMenu, this.FavRemoveToolStripMenuItem, this.ToolStripSeparator2, - this.ShowProfileMenuItem, this.ShowRelatedStatusesMenuItem, - this.ShowUserTimelineContextMenuItem, + this.AuthorContextMenuItem, + this.RetweetedByContextMenuItem, this.ToolStripMenuItem6, this.ToolStripMenuItem7, - this.ListManageUserContextToolStripMenuItem2, - this.ShowRetweeterProfileMenuItem, - this.ShowRetweeterUserTimelineContextMenuItem, this.ToolStripSeparator4, this.ToolStripMenuItem11, this.JumpUnreadMenuItem, @@ -1944,61 +1947,90 @@ private void InitializeComponent() this.ToolStripSeparator2.Name = "ToolStripSeparator2"; resources.ApplyResources(this.ToolStripSeparator2, "ToolStripSeparator2"); // - // ShowProfileMenuItem - // - this.ShowProfileMenuItem.Name = "ShowProfileMenuItem"; - resources.ApplyResources(this.ShowProfileMenuItem, "ShowProfileMenuItem"); - this.ShowProfileMenuItem.Click += new System.EventHandler(this.ShowProfileMenuItem_Click); - // // ShowRelatedStatusesMenuItem // this.ShowRelatedStatusesMenuItem.Name = "ShowRelatedStatusesMenuItem"; resources.ApplyResources(this.ShowRelatedStatusesMenuItem, "ShowRelatedStatusesMenuItem"); this.ShowRelatedStatusesMenuItem.Click += new System.EventHandler(this.ShowRelatedStatusesMenuItem_Click); // - // ShowUserTimelineContextMenuItem + // AuthorContextMenuItem + // + this.AuthorContextMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.AuthorShowProfileContextMenuItem, + this.AuthorShowUserTimelineContextMenuItem, + this.AuthorListManageContextMenuItem, + this.AuthorOpenInBrowserContextMenuItem, + this.AuthorOpenFavoritesContextMenuItem}); + this.AuthorContextMenuItem.Name = "AuthorContextMenuItem"; + resources.ApplyResources(this.AuthorContextMenuItem, "AuthorContextMenuItem"); + // + // AuthorShowProfileContextMenuItem + // + this.AuthorShowProfileContextMenuItem.Name = "AuthorShowProfileContextMenuItem"; + resources.ApplyResources(this.AuthorShowProfileContextMenuItem, "AuthorShowProfileContextMenuItem"); + this.AuthorShowProfileContextMenuItem.Click += new System.EventHandler(this.AuthorShowProfileMenuItem_Click); + // + // AuthorShowUserTimelineContextMenuItem + // + this.AuthorShowUserTimelineContextMenuItem.Name = "AuthorShowUserTimelineContextMenuItem"; + resources.ApplyResources(this.AuthorShowUserTimelineContextMenuItem, "AuthorShowUserTimelineContextMenuItem"); + this.AuthorShowUserTimelineContextMenuItem.Click += new System.EventHandler(this.AuthorShowUserTimelineMenuItem_Click); + // + // AuthorListManageContextMenuItem // - this.ShowUserTimelineContextMenuItem.Name = "ShowUserTimelineContextMenuItem"; - resources.ApplyResources(this.ShowUserTimelineContextMenuItem, "ShowUserTimelineContextMenuItem"); - this.ShowUserTimelineContextMenuItem.Click += new System.EventHandler(this.ShowUserTimelineToolStripMenuItem_Click); + this.AuthorListManageContextMenuItem.Name = "AuthorListManageContextMenuItem"; + resources.ApplyResources(this.AuthorListManageContextMenuItem, "AuthorListManageContextMenuItem"); + this.AuthorListManageContextMenuItem.Click += new System.EventHandler(this.AuthorListManageMenuItem_Click); // - // ShowRetweeterProfileMenuItem + // AuthorOpenInBrowserContextMenuItem // - this.ShowRetweeterProfileMenuItem.Name = "ShowRetweeterProfileMenuItem"; - resources.ApplyResources(this.ShowRetweeterProfileMenuItem, "ShowRetweeterProfileMenuItem"); - this.ShowRetweeterProfileMenuItem.Click += new System.EventHandler(this.ShowRetweeterProfileMenuItem_Click); + this.AuthorOpenInBrowserContextMenuItem.Name = "AuthorOpenInBrowserContextMenuItem"; + resources.ApplyResources(this.AuthorOpenInBrowserContextMenuItem, "AuthorOpenInBrowserContextMenuItem"); + this.AuthorOpenInBrowserContextMenuItem.Click += new System.EventHandler(this.AuthorOpenInBrowserMenuItem_Click); // - // ShowRetweeterUserTimelineContextMenuItem + // AuthorOpenFavoritesContextMenuItem // - this.ShowRetweeterUserTimelineContextMenuItem.Name = "ShowRetweeterUserTimelineContextMenuItem"; - resources.ApplyResources(this.ShowRetweeterUserTimelineContextMenuItem, "ShowRetweeterUserTimelineContextMenuItem"); - this.ShowRetweeterUserTimelineContextMenuItem.Click += new System.EventHandler(this.ShowRetweeterUserTimelineToolStripMenuItem_Click); + this.AuthorOpenFavoritesContextMenuItem.Name = "AuthorOpenFavoritesContextMenuItem"; + resources.ApplyResources(this.AuthorOpenFavoritesContextMenuItem, "AuthorOpenFavoritesContextMenuItem"); + this.AuthorOpenFavoritesContextMenuItem.Click += new System.EventHandler(this.AuthorOpenFavoritesMenuItem_Click); + // + // RetweetedByContextMenuItem + // + this.RetweetedByContextMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.RetweetedByShowProfileContextMenuItem, + this.RetweetedByShowUserTimelineContextMenuItem, + this.RetweetedByOpenInBrowserContextMenuItem}); + this.RetweetedByContextMenuItem.Name = "RetweetedByContextMenuItem"; + resources.ApplyResources(this.RetweetedByContextMenuItem, "RetweetedByContextMenuItem"); + // + // RetweetedByShowProfileContextMenuItem + // + this.RetweetedByShowProfileContextMenuItem.Name = "RetweetedByShowProfileContextMenuItem"; + resources.ApplyResources(this.RetweetedByShowProfileContextMenuItem, "RetweetedByShowProfileContextMenuItem"); + this.RetweetedByShowProfileContextMenuItem.Click += new System.EventHandler(this.RetweetedByShowProfileMenuItem_Click); + // + // RetweetedByShowUserTimelineContextMenuItem + // + this.RetweetedByShowUserTimelineContextMenuItem.Name = "RetweetedByShowUserTimelineContextMenuItem"; + resources.ApplyResources(this.RetweetedByShowUserTimelineContextMenuItem, "RetweetedByShowUserTimelineContextMenuItem"); + this.RetweetedByShowUserTimelineContextMenuItem.Click += new System.EventHandler(this.RetweetedByShowUserTimelineMenuItem_Click); + // + // RetweetedByOpenInBrowserContextMenuItem + // + this.RetweetedByOpenInBrowserContextMenuItem.Name = "RetweetedByOpenInBrowserContextMenuItem"; + resources.ApplyResources(this.RetweetedByOpenInBrowserContextMenuItem, "RetweetedByOpenInBrowserContextMenuItem"); + this.RetweetedByOpenInBrowserContextMenuItem.Click += new System.EventHandler(this.RetweetedByOpenInBrowserMenuItem_Click); // // ToolStripMenuItem6 // this.ToolStripMenuItem6.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.MoveToHomeToolStripMenuItem, - this.MoveToFavToolStripMenuItem, this.StatusOpenMenuItem, this.RepliedStatusOpenMenuItem, this.OpenURLMenuItem, - this.MoveToRTHomeMenuItem, this.OpenUserSpecifiedUrlMenuItem2}); this.ToolStripMenuItem6.Name = "ToolStripMenuItem6"; resources.ApplyResources(this.ToolStripMenuItem6, "ToolStripMenuItem6"); // - // MoveToHomeToolStripMenuItem - // - this.MoveToHomeToolStripMenuItem.Name = "MoveToHomeToolStripMenuItem"; - resources.ApplyResources(this.MoveToHomeToolStripMenuItem, "MoveToHomeToolStripMenuItem"); - this.MoveToHomeToolStripMenuItem.Click += new System.EventHandler(this.MoveToHomeToolStripMenuItem_Click); - // - // MoveToFavToolStripMenuItem - // - this.MoveToFavToolStripMenuItem.Name = "MoveToFavToolStripMenuItem"; - resources.ApplyResources(this.MoveToFavToolStripMenuItem, "MoveToFavToolStripMenuItem"); - this.MoveToFavToolStripMenuItem.Click += new System.EventHandler(this.MoveToFavToolStripMenuItem_Click); - // // TimerRefreshIcon // this.TimerRefreshIcon.Tick += new System.EventHandler(this.TimerRefreshIcon_Tick); @@ -2222,23 +2254,15 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripMenuItem FavoriteRetweetUnofficialMenuItem; internal System.Windows.Forms.ToolStripMenuItem UnFavOpMenuItem; internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator38; - internal System.Windows.Forms.ToolStripMenuItem ShowProfMenuItem; internal System.Windows.Forms.ToolStripMenuItem ShowRelatedStatusesMenuItem2; - internal System.Windows.Forms.ToolStripMenuItem ShowUserTimelineToolStripMenuItem; - internal System.Windows.Forms.ToolStripMenuItem ShowRetweeterProfMenuItem; - internal System.Windows.Forms.ToolStripMenuItem ShowRetweeterUserTimelineToolStripMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenOpMenuItem; - internal System.Windows.Forms.ToolStripMenuItem OpenHomeOpMenuItem; - internal System.Windows.Forms.ToolStripMenuItem OpenFavOpMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenStatusOpMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenRepSourceOpMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenUrlOpMenuItem; - internal System.Windows.Forms.ToolStripMenuItem OpenRterHomeMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenUserSpecifiedUrlMenuItem; internal System.Windows.Forms.ToolStripMenuItem CreateRuleOpMenuItem; internal System.Windows.Forms.ToolStripMenuItem CreateTabRuleOpMenuItem; internal System.Windows.Forms.ToolStripMenuItem CreateIdRuleOpMenuItem; - internal System.Windows.Forms.ToolStripMenuItem ListManageMenuItem; internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator26; internal System.Windows.Forms.ToolStripMenuItem ChangeReadOpMenuItem; internal System.Windows.Forms.ToolStripMenuItem ReadOpMenuItem; @@ -2304,10 +2328,8 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripMenuItem JumpUnreadMenuItem; internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator4; internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator10; - internal System.Windows.Forms.ToolStripMenuItem ListManageUserContextToolStripMenuItem2; internal System.Windows.Forms.ToolStripMenuItem OpenURLMenuItem; internal System.Windows.Forms.ToolStripMenuItem IDRuleMenuItem; - internal System.Windows.Forms.ToolStripMenuItem MoveToRTHomeMenuItem; internal System.Windows.Forms.ToolStripMenuItem TabMenuItem; internal System.Windows.Forms.ToolStripMenuItem OpenUserSpecifiedUrlMenuItem2; internal System.Windows.Forms.ToolStripMenuItem DeleteStripMenuItem; @@ -2342,14 +2364,8 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripMenuItem FavoriteRetweetUnofficialContextMenu; internal System.Windows.Forms.ToolStripMenuItem FavRemoveToolStripMenuItem; internal System.Windows.Forms.ToolStripSeparator ToolStripSeparator2; - internal System.Windows.Forms.ToolStripMenuItem ShowProfileMenuItem; internal System.Windows.Forms.ToolStripMenuItem ShowRelatedStatusesMenuItem; - internal System.Windows.Forms.ToolStripMenuItem ShowUserTimelineContextMenuItem; - internal System.Windows.Forms.ToolStripMenuItem ShowRetweeterProfileMenuItem; - internal System.Windows.Forms.ToolStripMenuItem ShowRetweeterUserTimelineContextMenuItem; internal System.Windows.Forms.ToolStripMenuItem ToolStripMenuItem6; - internal System.Windows.Forms.ToolStripMenuItem MoveToHomeToolStripMenuItem; - internal System.Windows.Forms.ToolStripMenuItem MoveToFavToolStripMenuItem; internal System.Windows.Forms.ToolTip ToolTip1; internal System.Windows.Forms.Timer TimerRefreshIcon; internal System.Windows.Forms.ImageList PostStateImageList; @@ -2385,5 +2401,25 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripSeparator toolStripSeparator13; internal System.Windows.Forms.ToolStripMenuItem HashToggleMenuItem; internal System.Windows.Forms.ToolStripMenuItem HashManageMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorShowProfileMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorShowUserTimelineMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorListManageMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorOpenInBrowserMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorOpenFavoritesMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByShowProfileMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByShowUserTimelineMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByOpenInBrowserMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorShowProfileContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorShowUserTimelineContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorListManageContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorOpenInBrowserContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem AuthorOpenFavoritesContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByShowProfileContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByShowUserTimelineContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByOpenInBrowserContextMenuItem; } } \ No newline at end of file diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 80d6d5289..963ba4ded 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2920,7 +2920,7 @@ private async void MyList_MouseDoubleClick(object sender, MouseEventArgs e) this.ShowRelatedStatusesMenuItem_Click(this.ShowRelatedStatusesMenuItem, EventArgs.Empty); break; case 5: - this.MoveToHomeToolStripMenuItem_Click(this.MoveToHomeToolStripMenuItem, EventArgs.Empty); + this.AuthorOpenInBrowserMenuItem_Click(this.AuthorOpenInBrowserContextMenuItem, EventArgs.Empty); break; case 6: this.StatusOpenMenuItem_Click(this.StatusOpenMenuItem, EventArgs.Empty); @@ -3015,7 +3015,7 @@ private PostClass GetCurTabPost(int index) return this.CurrentTab[index]; } - private async void MoveToHomeToolStripMenuItem_Click(object sender, EventArgs e) + private async void AuthorOpenInBrowserMenuItem_Click(object sender, EventArgs e) { var post = this.CurrentPost; if (post != null) @@ -3024,7 +3024,7 @@ private async void MoveToHomeToolStripMenuItem_Click(object sender, EventArgs e) await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl); } - private async void MoveToFavToolStripMenuItem_Click(object sender, EventArgs e) + private async void AuthorOpenFavoritesMenuItem_Click(object sender, EventArgs e) { var post = this.CurrentPost; if (post != null) @@ -3167,38 +3167,36 @@ private void TweenMain_LocationChanged(object sender, EventArgs e) private void ContextMenuOperate_Opening(object sender, CancelEventArgs e) { + var post = this.CurrentPost; if (!this.ExistCurrentPost) { this.ReplyStripMenuItem.Enabled = false; this.ReplyAllStripMenuItem.Enabled = false; this.DMStripMenuItem.Enabled = false; - this.ShowProfileMenuItem.Enabled = false; - this.ShowUserTimelineContextMenuItem.Enabled = false; - this.ListManageUserContextToolStripMenuItem2.Enabled = false; - this.MoveToFavToolStripMenuItem.Enabled = false; this.TabMenuItem.Enabled = false; this.IDRuleMenuItem.Enabled = false; this.SourceRuleMenuItem.Enabled = false; this.ReadedStripMenuItem.Enabled = false; this.UnreadStripMenuItem.Enabled = false; + this.AuthorContextMenuItem.Visible = false; + this.RetweetedByContextMenuItem.Visible = false; } else { - this.ShowProfileMenuItem.Enabled = true; - this.ListManageUserContextToolStripMenuItem2.Enabled = true; this.ReplyStripMenuItem.Enabled = true; this.ReplyAllStripMenuItem.Enabled = true; this.DMStripMenuItem.Enabled = true; - this.ShowUserTimelineContextMenuItem.Enabled = true; - this.MoveToFavToolStripMenuItem.Enabled = true; this.TabMenuItem.Enabled = true; this.IDRuleMenuItem.Enabled = true; this.SourceRuleMenuItem.Enabled = true; this.ReadedStripMenuItem.Enabled = true; this.UnreadStripMenuItem.Enabled = true; + this.AuthorContextMenuItem.Visible = true; + this.AuthorContextMenuItem.Text = $"@{post!.ScreenName}"; + this.RetweetedByContextMenuItem.Visible = post.RetweetedByUserId != null; + this.RetweetedByContextMenuItem.Text = $"@{post.RetweetedBy}"; } var tab = this.CurrentTab; - var post = this.CurrentPost; if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post == null || post.IsDm) { this.FavAddToolStripMenuItem.Enabled = false; @@ -3245,14 +3243,6 @@ private void ContextMenuOperate_Opening(object sender, CancelEventArgs e) { this.RepliedStatusOpenMenuItem.Enabled = true; } - if (!this.ExistCurrentPost || post == null || MyCommon.IsNullOrEmpty(post.RetweetedBy)) - { - this.MoveToRTHomeMenuItem.Enabled = false; - } - else - { - this.MoveToRTHomeMenuItem.Enabled = true; - } if (this.ExistCurrentPost && post != null) { @@ -5832,10 +5822,10 @@ private void InitializeShortcuts() .Do(() => this.ShowUserTimeline()), ShortcutCommand.Create(Keys.Control | Keys.H) - .Do(() => this.MoveToHomeToolStripMenuItem_Click(this.MoveToHomeToolStripMenuItem, EventArgs.Empty)), + .Do(() => this.AuthorOpenInBrowserMenuItem_Click(this.AuthorOpenInBrowserContextMenuItem, EventArgs.Empty)), ShortcutCommand.Create(Keys.Control | Keys.G) - .Do(() => this.MoveToFavToolStripMenuItem_Click(this.MoveToFavToolStripMenuItem, EventArgs.Empty)), + .Do(() => this.AuthorOpenFavoritesMenuItem_Click(this.AuthorOpenFavoritesContextMenuItem, EventArgs.Empty)), ShortcutCommand.Create(Keys.Control | Keys.O) .Do(() => this.StatusOpenMenuItem_Click(this.StatusOpenMenuItem, EventArgs.Empty)), @@ -10376,10 +10366,10 @@ private async Task DoMoveToRTHome() await MyCommon.OpenInBrowserAsync(this, "https://twitter.com/" + post.RetweetedBy); } - private async void MoveToRTHomeMenuItem_Click(object sender, EventArgs e) + private async void RetweetedByOpenInBrowserMenuItem_Click(object sender, EventArgs e) => await this.DoMoveToRTHome(); - private void ListManageUserContextToolStripMenuItem_Click(object sender, EventArgs e) + private void AuthorListManageMenuItem_Click(object sender, EventArgs e) { var screenName = this.CurrentPost?.ScreenName; if (screenName != null) @@ -10491,35 +10481,28 @@ private void MenuItemOperate_DropDownOpening(object sender, EventArgs e) this.ReplyOpMenuItem.Enabled = false; this.ReplyAllOpMenuItem.Enabled = false; this.DmOpMenuItem.Enabled = false; - this.ShowProfMenuItem.Enabled = false; - this.ShowUserTimelineToolStripMenuItem.Enabled = false; - this.ShowRetweeterProfMenuItem.Enabled = false; - this.ShowRetweeterUserTimelineToolStripMenuItem.Enabled = false; - this.ListManageMenuItem.Enabled = false; - this.OpenFavOpMenuItem.Enabled = false; this.CreateTabRuleOpMenuItem.Enabled = false; this.CreateIdRuleOpMenuItem.Enabled = false; this.CreateSourceRuleOpMenuItem.Enabled = false; this.ReadOpMenuItem.Enabled = false; this.UnreadOpMenuItem.Enabled = false; + this.AuthorMenuItem.Visible = false; + this.RetweetedByMenuItem.Visible = false; } else { this.ReplyOpMenuItem.Enabled = true; this.ReplyAllOpMenuItem.Enabled = true; this.DmOpMenuItem.Enabled = true; - this.ShowProfMenuItem.Enabled = true; - this.ShowUserTimelineToolStripMenuItem.Enabled = true; - this.ShowRetweeterProfMenuItem.Enabled - = this.ShowRetweeterUserTimelineToolStripMenuItem.Enabled - = post?.RetweetedByUserId != null; - this.ListManageMenuItem.Enabled = true; - this.OpenFavOpMenuItem.Enabled = true; this.CreateTabRuleOpMenuItem.Enabled = true; this.CreateIdRuleOpMenuItem.Enabled = true; this.CreateSourceRuleOpMenuItem.Enabled = true; this.ReadOpMenuItem.Enabled = true; this.UnreadOpMenuItem.Enabled = true; + this.AuthorMenuItem.Visible = true; + this.AuthorMenuItem.Text = $"@{post!.ScreenName}"; + this.RetweetedByMenuItem.Visible = post.RetweetedByUserId != null; + this.RetweetedByMenuItem.Text = $"@{post.RetweetedBy}"; } if (tab.TabType == MyCommon.TabUsageType.DirectMessage || !this.ExistCurrentPost || post == null || post.IsDm) @@ -10575,14 +10558,6 @@ private void MenuItemOperate_DropDownOpening(object sender, EventArgs e) { this.OpenRepSourceOpMenuItem.Enabled = true; } - if (!this.ExistCurrentPost || post == null || MyCommon.IsNullOrEmpty(post.RetweetedBy)) - { - this.OpenRterHomeMenuItem.Enabled = false; - } - else - { - this.OpenRterHomeMenuItem.Enabled = true; - } if (this.ExistCurrentPost && post != null) { @@ -10722,7 +10697,7 @@ internal Task ShowUserStatus(string id, bool showInputDialog) internal Task ShowUserStatus(string id) => this.DoShowUserStatus(id, true); - private async void ShowProfileMenuItem_Click(object sender, EventArgs e) + private async void AuthorShowProfileMenuItem_Click(object sender, EventArgs e) { var post = this.CurrentPost; if (post != null) @@ -10731,7 +10706,7 @@ private async void ShowProfileMenuItem_Click(object sender, EventArgs e) } } - private async void ShowRetweeterProfileMenuItem_Click(object sender, EventArgs e) + private async void RetweetedByShowProfileMenuItem_Click(object sender, EventArgs e) { var retweetedBy = this.CurrentPost?.RetweetedBy; if (retweetedBy != null) @@ -11080,10 +11055,10 @@ private bool ExistCurrentPost } } - private async void ShowUserTimelineToolStripMenuItem_Click(object sender, EventArgs e) + private async void AuthorShowUserTimelineMenuItem_Click(object sender, EventArgs e) => await this.ShowUserTimeline(); - private async void ShowRetweeterUserTimelineToolStripMenuItem_Click(object sender, EventArgs e) + private async void RetweetedByShowUserTimelineMenuItem_Click(object sender, EventArgs e) => await this.ShowRetweeterTimeline(); private string GetUserIdFromCurPostOrInput(string caption) diff --git a/OpenTween/Tween.en.resx b/OpenTween/Tween.en.resx index 4f1f7c4b7..8086090e5 100644 --- a/OpenTween/Tween.en.resx +++ b/OpenTween/Tween.en.resx @@ -14,6 +14,28 @@ Create &New Tab... 278, 24 Twitter API Usage + 200, 22 + 197, 22 + Add/Remove from &Lists + 223, 22 + Add/Remove from &Lists + 259, 22 + 197, 22 + Open Favorites (&G) + 223, 22 + Open Favorites (&G) + 197, 22 + Open in browser (&H) + 223, 22 + Open in browser (&H) + 197, 22 + User &Profile + 223, 22 + User &Profile + 197, 22 + User's updates + 223, 22 + User's updates 218, 24 347, 24 Change Unread state ... @@ -131,12 +153,8 @@ 247, 24 Stick &List - 347, 24 - Manage &Lists 294, 24 Edit Lists - 258, 24 - Add to &Lists 570, 149 242, 24 @@ -164,12 +182,6 @@ &Tab 574, 27 - 245, 24 - Open Favorites (&G) - 245, 24 - Open &Home page - 245, 24 - Open &Retweeter Home 334, 22 Input field is &Multiline 445, 24 @@ -182,18 +194,12 @@ Enable Alert popup(&Q) 248, 24 Enable Alert Popup(&Q) - 306, 24 - Favorites(&G) - 306, 24 - &Home 347, 24 &Open as ... 294, 24 Open your profile page 306, 24 Reply to(&I) - 306, 24 - &Retweeter Home 306, 24 Status(&O) Open URL(&L)... @@ -387,6 +393,20 @@ @&Reply 258, 24 @ &Reply + 200, 22 + 259, 22 + 181, 22 + Open in browser (&H) + 255, 22 + Open in browser (&H) + 181, 22 + User &Profile + 255, 22 + User &Profile + 181, 22 + User's updates + 255, 22 + User's updates 258, 24 258, 24 294, 24 @@ -407,26 +427,10 @@ Settings (&O)... 278, 24 Shortcut keys - 258, 24 - User &Profile - 347, 24 - User &Profile 258, 24 Related Posts (&G) 347, 24 Related Posts (&G) - 258, 24 - Retweeter &Profile - 347, 24 - Retweeter &Profile - 258, 24 - &Retweeter's updates - 347, 24 - Retweeter's updates - 258, 24 - &User's updates - 347, 24 - User's updates Select a wav file. 122, 22 &Source diff --git a/OpenTween/Tween.resx b/OpenTween/Tween.resx index 5deab6f97..03614f0eb 100644 --- a/OpenTween/Tween.resx +++ b/OpenTween/Tween.resx @@ -22,6 +22,30 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ApiUsageInfoMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorListManageContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorListManageMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorOpenFavoritesContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorOpenFavoritesMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorOpenInBrowserContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorOpenInBrowserMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorShowProfileContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorShowProfileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorShowUserTimelineContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorShowUserTimelineMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 BitlyToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 CacheInfoMenuItem @@ -154,12 +178,8 @@ 2 ListLockMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ListManageMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ListManageToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ListManageUserContextToolStripMenuItem2 - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ListTab TimelinePanel System.Windows.Forms.TabControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -192,12 +212,6 @@ ToolStripContainer1.TopToolStripPanel System.Windows.Forms.MenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 0 - MoveToFavToolStripMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - MoveToHomeToolStripMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - MoveToRTHomeMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 MultiLineMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 MultiLinePullDownMenuItem @@ -212,20 +226,14 @@ System.Windows.Forms.NotifyIcon, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 NotifyTbMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - OpenFavOpMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 OpenFileDialog1 System.Windows.Forms.OpenFileDialog, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - OpenHomeOpMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 OpenOpMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 OpenOwnHomeMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 OpenRepSourceOpMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - OpenRterHomeMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 OpenStatusOpMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 OpenURLFileMenuItem @@ -296,6 +304,22 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ReplyStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByOpenInBrowserContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByOpenInBrowserMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByShowProfileContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByShowProfileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByShowUserTimelineContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByShowUserTimelineMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ReTweetStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ReTweetUnofficialStripMenuItem @@ -322,26 +346,10 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShortcutKeyListMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ShowProfileMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ShowProfMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShowRelatedStatusesMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShowRelatedStatusesMenuItem2 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ShowProfileMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ShowProfMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ShowUserTimelineContextMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ShowUserTimelineToolStripMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ShowUserTimelineContextMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - ShowUserTimelineToolStripMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 SoundFileComboBox System.Windows.Forms.ToolStripComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 SoundFileTbComboBox @@ -586,6 +594,35 @@ タブ作成(&N)... 251, 22 Twitter API 使用情報 + 224, 22 + %Author% + 206, 22 + リスト管理(&L) + 247, 22 + リスト管理(&L) + 244, 22 + %Author% + 206, 22 + Favを開く(&G) + Ctrl+G + 247, 22 + Favを開く(&G) + 206, 22 + ブラウザで開く(&H) + Ctrl+H + 247, 22 + ブラウザで開く(&H) + 206, 22 + プロフィール表示 + + Alt+P + 247, 22 + プロフィール表示 + 206, 22 + ユーザーのタイムラインを表示 + Ctrl+U + 247, 22 + ユーザーのタイムラインを表示 228, 22 bit.ly 200, 22 @@ -736,12 +773,8 @@ MiddleCenter 175, 22 新着時リスト固定(&L) - 313, 22 - リスト管理(&L) 257, 22 リスト編集 - 241, 22 - リスト管理(&L) Bottom Fill Disable @@ -783,12 +816,6 @@ 0 MenuStrip1 531, 17 - 205, 22 - Favを開く(&G) - 205, 22 - ホームを開く(&H) - 205, 22 - RTした人のホームを開く(&R) Ctrl+Y 246, 22 発言欄複数行入力(&M) @@ -805,13 +832,7 @@ 395, 55 199, 22 新着通知表示(&Q) - Ctrl+G - 289, 22 - Favを開く(&G) 681, 93 - Ctrl+H - 289, 22 - ホームを開く(&H) 313, 22 開く(&O) 257, 22 @@ -819,9 +840,6 @@ Ctrl+I 289, 22 返信元ステータスを開く(&I) - Ctrl+Shift+H - 289, 22 - RTした人のホームを開く(&R) Ctrl+O 289, 22 ステータスを開く(&O) @@ -1036,6 +1054,23 @@ @返信(&R) 241, 22 @返信(&R) + 224, 22 + %RetweetedBy% + 244, 22 + %RetweetedBy% + 206, 22 + ブラウザで開く(&H) + Ctrl+Shift+H + 230, 22 + ブラウザで開く(&H) + 206, 22 + プロフィール表示 + 230, 22 + プロフィール表示 + 206, 22 + ユーザーのタイムラインを表示 + 230, 22 + ユーザーのタイムラインを表示 241, 22 Re&tweet 241, 22 @@ -1064,29 +1099,10 @@ 設定(&O)... 251, 22 ショートカットキー一覧 - 241, 22 - プロフィール表示 - - Alt+P - 313, 22 - プロフィール表示 241, 22 関連発言表示(&G) 313, 22 関連発言表示(&G) - 258, 24 - RT元のプロフィール表示 - 347, 24 - RT元のプロフィール表示 - 258, 24 - RT元ユーザーのタイムラインを表示 - 347, 24 - RT元ユーザーのタイムラインを表示 - 241, 22 - ユーザーのタイムラインを表示 - Ctrl+U - 313, 22 - ユーザーのタイムラインを表示 121, 23 再生するwavファイルを指定してください 121, 23 From 57d21ad6ee5878c2edacc9a8904661275836ed6f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 13 Feb 2022 17:11:11 +0900 Subject: [PATCH 117/402] =?UTF-8?q?=E6=93=8D=E4=BD=9C=E3=83=A1=E3=83=8B?= =?UTF-8?q?=E3=83=A5=E3=83=BC=E3=81=8B=E3=82=89=E3=80=8CFav=E3=82=92?= =?UTF-8?q?=E9=96=8B=E3=81=8F=E3=80=8D=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Tween.Designer.cs | 22 ++-------------------- OpenTween/Tween.cs | 10 ---------- OpenTween/Tween.en.resx | 4 ---- OpenTween/Tween.resx | 9 --------- 4 files changed, 2 insertions(+), 43 deletions(-) diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index 0523437d9..717a2c1cc 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -110,7 +110,6 @@ private void InitializeComponent() this.AuthorShowUserTimelineMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorListManageMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorOpenInBrowserMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.AuthorOpenFavoritesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByShowProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByShowUserTimelineMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -247,7 +246,6 @@ private void InitializeComponent() this.AuthorShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorListManageContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorOpenInBrowserContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.AuthorOpenFavoritesContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByShowProfileContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -1020,8 +1018,7 @@ private void InitializeComponent() this.AuthorShowProfileMenuItem, this.AuthorShowUserTimelineMenuItem, this.AuthorListManageMenuItem, - this.AuthorOpenInBrowserMenuItem, - this.AuthorOpenFavoritesMenuItem}); + this.AuthorOpenInBrowserMenuItem}); this.AuthorMenuItem.Name = "AuthorMenuItem"; resources.ApplyResources(this.AuthorMenuItem, "AuthorMenuItem"); // @@ -1049,12 +1046,6 @@ private void InitializeComponent() resources.ApplyResources(this.AuthorOpenInBrowserMenuItem, "AuthorOpenInBrowserMenuItem"); this.AuthorOpenInBrowserMenuItem.Click += new System.EventHandler(this.AuthorOpenInBrowserMenuItem_Click); // - // AuthorOpenFavoritesMenuItem - // - this.AuthorOpenFavoritesMenuItem.Name = "AuthorOpenFavoritesMenuItem"; - resources.ApplyResources(this.AuthorOpenFavoritesMenuItem, "AuthorOpenFavoritesMenuItem"); - this.AuthorOpenFavoritesMenuItem.Click += new System.EventHandler(this.AuthorOpenFavoritesMenuItem_Click); - // // RetweetedByMenuItem // this.RetweetedByMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -1959,8 +1950,7 @@ private void InitializeComponent() this.AuthorShowProfileContextMenuItem, this.AuthorShowUserTimelineContextMenuItem, this.AuthorListManageContextMenuItem, - this.AuthorOpenInBrowserContextMenuItem, - this.AuthorOpenFavoritesContextMenuItem}); + this.AuthorOpenInBrowserContextMenuItem}); this.AuthorContextMenuItem.Name = "AuthorContextMenuItem"; resources.ApplyResources(this.AuthorContextMenuItem, "AuthorContextMenuItem"); // @@ -1988,12 +1978,6 @@ private void InitializeComponent() resources.ApplyResources(this.AuthorOpenInBrowserContextMenuItem, "AuthorOpenInBrowserContextMenuItem"); this.AuthorOpenInBrowserContextMenuItem.Click += new System.EventHandler(this.AuthorOpenInBrowserMenuItem_Click); // - // AuthorOpenFavoritesContextMenuItem - // - this.AuthorOpenFavoritesContextMenuItem.Name = "AuthorOpenFavoritesContextMenuItem"; - resources.ApplyResources(this.AuthorOpenFavoritesContextMenuItem, "AuthorOpenFavoritesContextMenuItem"); - this.AuthorOpenFavoritesContextMenuItem.Click += new System.EventHandler(this.AuthorOpenFavoritesMenuItem_Click); - // // RetweetedByContextMenuItem // this.RetweetedByContextMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -2406,7 +2390,6 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem AuthorShowUserTimelineMenuItem; private System.Windows.Forms.ToolStripMenuItem AuthorListManageMenuItem; private System.Windows.Forms.ToolStripMenuItem AuthorOpenInBrowserMenuItem; - private System.Windows.Forms.ToolStripMenuItem AuthorOpenFavoritesMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByShowProfileMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByShowUserTimelineMenuItem; @@ -2416,7 +2399,6 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem AuthorShowUserTimelineContextMenuItem; private System.Windows.Forms.ToolStripMenuItem AuthorListManageContextMenuItem; private System.Windows.Forms.ToolStripMenuItem AuthorOpenInBrowserContextMenuItem; - private System.Windows.Forms.ToolStripMenuItem AuthorOpenFavoritesContextMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByContextMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByShowProfileContextMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByShowUserTimelineContextMenuItem; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 963ba4ded..d2e477de9 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -3024,13 +3024,6 @@ private async void AuthorOpenInBrowserMenuItem_Click(object sender, EventArgs e) await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl); } - private async void AuthorOpenFavoritesMenuItem_Click(object sender, EventArgs e) - { - var post = this.CurrentPost; - if (post != null) - await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl + "#!/" + post.ScreenName + "/favorites"); - } - private void TweenMain_ClientSizeChanged(object sender, EventArgs e) { if ((!this.initialLayout) && this.Visible) @@ -5824,9 +5817,6 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Control | Keys.H) .Do(() => this.AuthorOpenInBrowserMenuItem_Click(this.AuthorOpenInBrowserContextMenuItem, EventArgs.Empty)), - ShortcutCommand.Create(Keys.Control | Keys.G) - .Do(() => this.AuthorOpenFavoritesMenuItem_Click(this.AuthorOpenFavoritesContextMenuItem, EventArgs.Empty)), - ShortcutCommand.Create(Keys.Control | Keys.O) .Do(() => this.StatusOpenMenuItem_Click(this.StatusOpenMenuItem, EventArgs.Empty)), diff --git a/OpenTween/Tween.en.resx b/OpenTween/Tween.en.resx index 8086090e5..bb71eeda6 100644 --- a/OpenTween/Tween.en.resx +++ b/OpenTween/Tween.en.resx @@ -20,10 +20,6 @@ 223, 22 Add/Remove from &Lists 259, 22 - 197, 22 - Open Favorites (&G) - 223, 22 - Open Favorites (&G) 197, 22 Open in browser (&H) 223, 22 diff --git a/OpenTween/Tween.resx b/OpenTween/Tween.resx index 03614f0eb..bb94c2a05 100644 --- a/OpenTween/Tween.resx +++ b/OpenTween/Tween.resx @@ -30,10 +30,6 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 AuthorMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - AuthorOpenFavoritesContextMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - AuthorOpenFavoritesMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 AuthorOpenInBrowserContextMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 AuthorOpenInBrowserMenuItem @@ -602,11 +598,6 @@ リスト管理(&L) 244, 22 %Author% - 206, 22 - Favを開く(&G) - Ctrl+G - 247, 22 - Favを開く(&G) 206, 22 ブラウザで開く(&H) Ctrl+H From 95217f33d8b65b0d7df96839e3c902fb35421dff Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 19 Mar 2022 04:55:06 +0900 Subject: [PATCH 118/402] =?UTF-8?q?RT=E5=85=83=E3=83=A6=E3=83=BC=E3=82=B6?= =?UTF-8?q?=E3=83=BC=E3=81=AB=E5=AF=BE=E3=81=99=E3=82=8B=E3=80=8C=E3=83=AA?= =?UTF-8?q?=E3=82=B9=E3=83=88=E7=AE=A1=E7=90=86=E3=80=8D=E3=81=AE=E3=83=A1?= =?UTF-8?q?=E3=83=8B=E3=83=A5=E3=83=BC=E9=A0=85=E7=9B=AE=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Tween.Designer.cs | 18 ++++++++++++++++++ OpenTween/Tween.cs | 7 +++++++ OpenTween/Tween.en.resx | 4 ++++ OpenTween/Tween.resx | 8 ++++++++ 4 files changed, 37 insertions(+) diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index 717a2c1cc..8f12f98e9 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -113,6 +113,7 @@ private void InitializeComponent() this.RetweetedByMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByShowProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByShowUserTimelineMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByListManageMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByOpenInBrowserMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.OpenStatusOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -249,6 +250,7 @@ private void InitializeComponent() this.RetweetedByContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByShowProfileContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.RetweetedByListManageContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.RetweetedByOpenInBrowserContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripMenuItem6 = new System.Windows.Forms.ToolStripMenuItem(); this.ToolTip1 = new System.Windows.Forms.ToolTip(this.components); @@ -1051,6 +1053,7 @@ private void InitializeComponent() this.RetweetedByMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.RetweetedByShowProfileMenuItem, this.RetweetedByShowUserTimelineMenuItem, + this.RetweetedByListManageMenuItem, this.RetweetedByOpenInBrowserMenuItem}); this.RetweetedByMenuItem.Name = "RetweetedByMenuItem"; resources.ApplyResources(this.RetweetedByMenuItem, "RetweetedByMenuItem"); @@ -1067,6 +1070,12 @@ private void InitializeComponent() resources.ApplyResources(this.RetweetedByShowUserTimelineMenuItem, "RetweetedByShowUserTimelineMenuItem"); this.RetweetedByShowUserTimelineMenuItem.Click += new System.EventHandler(this.RetweetedByShowUserTimelineMenuItem_Click); // + // RetweetedByListManageMenuItem + // + this.RetweetedByListManageMenuItem.Name = "RetweetedByListManageMenuItem"; + resources.ApplyResources(this.RetweetedByListManageMenuItem, "RetweetedByListManageMenuItem"); + this.RetweetedByListManageMenuItem.Click += new System.EventHandler(this.RetweetedByListManageMenuItem_Click); + // // RetweetedByOpenInBrowserMenuItem // this.RetweetedByOpenInBrowserMenuItem.Name = "RetweetedByOpenInBrowserMenuItem"; @@ -1983,6 +1992,7 @@ private void InitializeComponent() this.RetweetedByContextMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.RetweetedByShowProfileContextMenuItem, this.RetweetedByShowUserTimelineContextMenuItem, + this.RetweetedByListManageContextMenuItem, this.RetweetedByOpenInBrowserContextMenuItem}); this.RetweetedByContextMenuItem.Name = "RetweetedByContextMenuItem"; resources.ApplyResources(this.RetweetedByContextMenuItem, "RetweetedByContextMenuItem"); @@ -1999,6 +2009,12 @@ private void InitializeComponent() resources.ApplyResources(this.RetweetedByShowUserTimelineContextMenuItem, "RetweetedByShowUserTimelineContextMenuItem"); this.RetweetedByShowUserTimelineContextMenuItem.Click += new System.EventHandler(this.RetweetedByShowUserTimelineMenuItem_Click); // + // RetweetedByListManageContextMenuItem + // + this.RetweetedByListManageContextMenuItem.Name = "RetweetedByListManageContextMenuItem"; + resources.ApplyResources(this.RetweetedByListManageContextMenuItem, "RetweetedByListManageContextMenuItem"); + this.RetweetedByListManageContextMenuItem.Click += new System.EventHandler(this.RetweetedByListManageMenuItem_Click); + // // RetweetedByOpenInBrowserContextMenuItem // this.RetweetedByOpenInBrowserContextMenuItem.Name = "RetweetedByOpenInBrowserContextMenuItem"; @@ -2393,6 +2409,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem RetweetedByMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByShowProfileMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByShowUserTimelineMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByListManageMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByOpenInBrowserMenuItem; private System.Windows.Forms.ToolStripMenuItem AuthorContextMenuItem; private System.Windows.Forms.ToolStripMenuItem AuthorShowProfileContextMenuItem; @@ -2402,6 +2419,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem RetweetedByContextMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByShowProfileContextMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByShowUserTimelineContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem RetweetedByListManageContextMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByOpenInBrowserContextMenuItem; } } \ No newline at end of file diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index d2e477de9..80250ba2c 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -10366,6 +10366,13 @@ private void AuthorListManageMenuItem_Click(object sender, EventArgs e) this.ListManageUserContext(screenName); } + private void RetweetedByListManageMenuItem_Click(object sender, EventArgs e) + { + var screenName = this.CurrentPost?.RetweetedBy; + if (screenName != null) + this.ListManageUserContext(screenName); + } + public void ListManageUserContext(string screenName) { using var listSelectForm = new MyLists(screenName, this.twitterApi); diff --git a/OpenTween/Tween.en.resx b/OpenTween/Tween.en.resx index bb71eeda6..dc4c7ccd4 100644 --- a/OpenTween/Tween.en.resx +++ b/OpenTween/Tween.en.resx @@ -390,6 +390,10 @@ 258, 24 @ &Reply 200, 22 + 197, 22 + Add/Remove from &Lists + 255, 22 + Add/Remove from &Lists 259, 22 181, 22 Open in browser (&H) diff --git a/OpenTween/Tween.resx b/OpenTween/Tween.resx index bb94c2a05..b171150a7 100644 --- a/OpenTween/Tween.resx +++ b/OpenTween/Tween.resx @@ -302,6 +302,10 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 RetweetedByContextMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByListManageContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByListManageMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 RetweetedByMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 RetweetedByOpenInBrowserContextMenuItem @@ -1047,6 +1051,10 @@ @返信(&R) 224, 22 %RetweetedBy% + 206, 22 + リスト管理(&L) + 230, 22 + リスト管理(&L) 244, 22 %RetweetedBy% 206, 22 From a5d824e6c64c60b1913e5e192ccc33204c259107 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 19 Mar 2022 06:21:25 +0900 Subject: [PATCH 119/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E8=A9=B3=E7=B4=B0?= =?UTF-8?q?=E6=AC=84=E3=81=AE=E5=90=8D=E5=89=8D=E3=83=A9=E3=83=99=E3=83=AB?= =?UTF-8?q?=E3=82=84=E3=82=A2=E3=82=A4=E3=82=B3=E3=83=B3=E3=81=AE=E3=82=AF?= =?UTF-8?q?=E3=83=AA=E3=83=83=E3=82=AF=E3=81=AB=E3=82=88=E3=82=8B=E3=83=97?= =?UTF-8?q?=E3=83=AD=E3=83=95=E3=82=A3=E3=83=BC=E3=83=AB=E3=81=AE=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/TweetDetailsView.Designer.cs | 50 +++++++++++++++++----- OpenTween/TweetDetailsView.cs | 57 ++++++++++++++++++-------- OpenTween/TweetDetailsView.resx | 56 ++++++++++++++++++------- 4 files changed, 120 insertions(+), 44 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 06419120c..3226ecc35 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Ver 2.5.1-dev(2022/xx/xx) * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) + * NEW: 発言詳細欄の名前やアイコンのクリックによるプロフィール表示に対応 * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) diff --git a/OpenTween/TweetDetailsView.Designer.cs b/OpenTween/TweetDetailsView.Designer.cs index c772718b0..a4c6843e4 100644 --- a/OpenTween/TweetDetailsView.Designer.cs +++ b/OpenTween/TweetDetailsView.Designer.cs @@ -45,7 +45,9 @@ private void InitializeComponent() this.IconNameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ReloadIconToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.SaveIconPictureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.NameLabel = new System.Windows.Forms.Label(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); + this.AuthorNameLinkLabel = new System.Windows.Forms.LinkLabel(); + this.RetweetedByLinkLabel = new System.Windows.Forms.LinkLabel(); this.PostBrowser = new System.Windows.Forms.WebBrowser(); this.ContextMenuPostBrowser = new System.Windows.Forms.ContextMenuStrip(this.components); this.SelectionSearchContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -81,6 +83,7 @@ private void InitializeComponent() this.TableLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.UserPicture)).BeginInit(); this.ContextMenuUserPicture.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); this.ContextMenuPostBrowser.SuspendLayout(); this.ContextMenuSource.SuspendLayout(); this.SuspendLayout(); @@ -89,7 +92,7 @@ private void InitializeComponent() // resources.ApplyResources(this.TableLayoutPanel1, "TableLayoutPanel1"); this.TableLayoutPanel1.Controls.Add(this.UserPicture, 0, 0); - this.TableLayoutPanel1.Controls.Add(this.NameLabel, 1, 0); + this.TableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 1, 0); this.TableLayoutPanel1.Controls.Add(this.PostBrowser, 1, 1); this.TableLayoutPanel1.Controls.Add(this.DateTimeLabel, 2, 0); this.TableLayoutPanel1.Controls.Add(this.SourceLinkLabel, 3, 0); @@ -102,12 +105,11 @@ private void InitializeComponent() this.UserPicture.BackColor = System.Drawing.Color.White; this.UserPicture.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.UserPicture.ContextMenuStrip = this.ContextMenuUserPicture; + this.UserPicture.Cursor = System.Windows.Forms.Cursors.Hand; this.UserPicture.Name = "UserPicture"; this.TableLayoutPanel1.SetRowSpan(this.UserPicture, 2); this.UserPicture.TabStop = false; - this.UserPicture.DoubleClick += new System.EventHandler(this.UserPicture_DoubleClick); - this.UserPicture.MouseEnter += new System.EventHandler(this.UserPicture_MouseEnter); - this.UserPicture.MouseLeave += new System.EventHandler(this.UserPicture_MouseLeave); + this.UserPicture.Click += new System.EventHandler(this.UserPicture_Click); // // ContextMenuUserPicture // @@ -199,12 +201,34 @@ private void InitializeComponent() resources.ApplyResources(this.SaveIconPictureToolStripMenuItem, "SaveIconPictureToolStripMenuItem"); this.SaveIconPictureToolStripMenuItem.Click += new System.EventHandler(this.SaveIconPictureToolStripMenuItem_Click); // - // NameLabel + // flowLayoutPanel1 // - this.NameLabel.AutoEllipsis = true; - resources.ApplyResources(this.NameLabel, "NameLabel"); - this.NameLabel.Name = "NameLabel"; - this.NameLabel.UseMnemonic = false; + resources.ApplyResources(this.flowLayoutPanel1, "flowLayoutPanel1"); + this.flowLayoutPanel1.Controls.Add(this.AuthorNameLinkLabel); + this.flowLayoutPanel1.Controls.Add(this.RetweetedByLinkLabel); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + // + // AuthorNameLinkLabel + // + this.AuthorNameLinkLabel.ActiveLinkColor = System.Drawing.SystemColors.ControlText; + resources.ApplyResources(this.AuthorNameLinkLabel, "AuthorNameLinkLabel"); + this.AuthorNameLinkLabel.AutoEllipsis = true; + this.AuthorNameLinkLabel.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline; + this.AuthorNameLinkLabel.LinkColor = System.Drawing.SystemColors.ControlText; + this.AuthorNameLinkLabel.Name = "AuthorNameLinkLabel"; + this.AuthorNameLinkLabel.TabStop = true; + this.AuthorNameLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.AuthorNameLinkLabel_LinkClicked); + // + // RetweetedByLinkLabel + // + this.RetweetedByLinkLabel.ActiveLinkColor = System.Drawing.SystemColors.ControlText; + resources.ApplyResources(this.RetweetedByLinkLabel, "RetweetedByLinkLabel"); + this.RetweetedByLinkLabel.AutoEllipsis = true; + this.RetweetedByLinkLabel.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline; + this.RetweetedByLinkLabel.LinkColor = System.Drawing.SystemColors.ControlText; + this.RetweetedByLinkLabel.Name = "RetweetedByLinkLabel"; + this.RetweetedByLinkLabel.TabStop = true; + this.RetweetedByLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.RetweetedByLinkLabel_LinkClicked); // // PostBrowser // @@ -445,6 +469,8 @@ private void InitializeComponent() this.TableLayoutPanel1.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.UserPicture)).EndInit(); this.ContextMenuUserPicture.ResumeLayout(false); + this.flowLayoutPanel1.ResumeLayout(false); + this.flowLayoutPanel1.PerformLayout(); this.ContextMenuPostBrowser.ResumeLayout(false); this.ContextMenuSource.ResumeLayout(false); this.ResumeLayout(false); @@ -455,7 +481,9 @@ private void InitializeComponent() internal System.Windows.Forms.TableLayoutPanel TableLayoutPanel1; internal OTPictureBox UserPicture; - internal System.Windows.Forms.Label NameLabel; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.LinkLabel AuthorNameLinkLabel; + private System.Windows.Forms.LinkLabel RetweetedByLinkLabel; internal System.Windows.Forms.WebBrowser PostBrowser; internal System.Windows.Forms.Label DateTimeLabel; internal System.Windows.Forms.LinkLabel SourceLinkLabel; diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 7dcdd7758..7032abb2d 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -78,7 +78,8 @@ public TweetDetailsView() this.TabStop = false; // 発言詳細部の初期化 - this.NameLabel.Text = ""; + this.AuthorNameLinkLabel.Text = ""; + this.RetweetedByLinkLabel.Text = ""; this.DateTimeLabel.Text = ""; this.SourceLinkLabel.Text = ""; @@ -110,10 +111,18 @@ public async Task ShowPostDetails(PostClass post) nameText = ""; } nameText += post.ScreenName + "/" + post.Nickname; - if (post.RetweetedId != null) - nameText += " (RT:" + post.RetweetedBy + ")"; + this.AuthorNameLinkLabel.Text = nameText; - this.NameLabel.Text = nameText; + if (post.RetweetedId != null) + { + this.RetweetedByLinkLabel.Visible = true; + this.RetweetedByLinkLabel.Text = $"(RT:{post.RetweetedBy})"; + } + else + { + this.RetweetedByLinkLabel.Visible = false; + this.RetweetedByLinkLabel.Text = ""; + } var nameForeColor = SystemColors.ControlText; if (post.IsOwl && (SettingManager.Common.OneWayLove || post.IsDm)) @@ -122,7 +131,11 @@ public async Task ShowPostDetails(PostClass post) nameForeColor = SettingManager.Local.ColorRetweet; if (post.IsFav) nameForeColor = SettingManager.Local.ColorFav; - this.NameLabel.ForeColor = nameForeColor; + + this.AuthorNameLinkLabel.LinkColor = nameForeColor; + this.AuthorNameLinkLabel.ActiveLinkColor = nameForeColor; + this.RetweetedByLinkLabel.LinkColor = nameForeColor; + this.RetweetedByLinkLabel.ActiveLinkColor = nameForeColor; loadTasks.Add(this.SetUserPictureAsync(post.ImageUrl)); @@ -420,26 +433,20 @@ protected void RaiseStatusChanged(string statusText) private void TweetDetailsView_FontChanged(object sender, EventArgs e) { // OTBaseForm.GlobalFont による UI フォントの変更に対応 - var origFont = this.NameLabel.Font; - this.NameLabel.Font = new Font(this.Font.Name, origFont.Size, origFont.Style); + var origFont = this.AuthorNameLinkLabel.Font; + this.AuthorNameLinkLabel.Font = new Font(this.Font.Name, origFont.Size, origFont.Style); + this.RetweetedByLinkLabel.Font = new Font(this.Font.Name, origFont.Size, origFont.Style); } #region TableLayoutPanel1 - private async void UserPicture_DoubleClick(object sender, EventArgs e) + private async void UserPicture_Click(object sender, EventArgs e) { - if (this.CurrentPost == null) - return; - - await MyCommon.OpenInBrowserAsync(this, MyCommon.TwitterUrl + this.CurrentPost.ScreenName); + var screenName = this.CurrentPost?.ScreenName; + if (screenName != null) + await this.Owner.ShowUserStatus(screenName, showInputDialog: false); } - private void UserPicture_MouseEnter(object sender, EventArgs e) - => this.UserPicture.Cursor = Cursors.Hand; - - private void UserPicture_MouseLeave(object sender, EventArgs e) - => this.UserPicture.Cursor = Cursors.Default; - private async void PostBrowser_Navigated(object sender, WebBrowserNavigatedEventArgs e) { if (e.Url.AbsoluteUri != "about:blank") @@ -1055,6 +1062,20 @@ private void SourceUrlCopyMenuItem_Click(object sender, EventArgs e) } #endregion + + private async void AuthorNameLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + var screenName = this.CurrentPost?.ScreenName; + if (screenName != null) + await this.Owner.ShowUserStatus(screenName, showInputDialog: false); + } + + private async void RetweetedByLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + var screenName = this.CurrentPost?.RetweetedBy; + if (screenName != null) + await this.Owner.ShowUserStatus(screenName, showInputDialog: false); + } } public class TweetDetailsViewStatusChengedEventArgs : EventArgs diff --git a/OpenTween/TweetDetailsView.resx b/OpenTween/TweetDetailsView.resx index 89f0daae2..f7c950d4e 100644 --- a/OpenTween/TweetDetailsView.resx +++ b/OpenTween/TweetDetailsView.resx @@ -12,6 +12,10 @@ 511, 85 TweetDetailsView System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + AuthorNameLinkLabel + flowLayoutPanel1 + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 0 ContextMenuPostBrowser System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ContextMenuSource @@ -24,6 +28,10 @@ TableLayoutPanel1 System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 3 + flowLayoutPanel1 + TableLayoutPanel1 + System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 4 FollowContextMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 FollowToolStripMenuItem @@ -40,10 +48,6 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ListManageUserContextToolStripMenuItem3 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - NameLabel - TableLayoutPanel1 - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 PostBrowser TableLayoutPanel1 System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -52,6 +56,10 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 RemoveContextMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + RetweetedByLinkLabel + flowLayoutPanel1 + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 SaveIconPictureToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 SearchAtPostsDetailNameToolStripMenuItem @@ -120,6 +128,15 @@ TableLayoutPanel1 OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null 0 + Bottom + True + MS UI Gothic, 9pt, style=Bold + 3, 3 + 3, 3, 0, 0 + 135, 12 + 0 + AuthorNameLinkLabel + MiddleLeft 232, 386 17, 17 168, 48 @@ -133,10 +150,18 @@ Off 405, 3 3, 3, 3, 0 - 38, 14 + 38, 12 1 Label1 MiddleRight + True + GrowAndShrink + Fill + 56, 0 + 0, 0, 0, 0 + 346, 15 + 0 + False 231, 22 フォローする(&F) 231, 22 @@ -153,15 +178,6 @@ リスト管理(&L) 231, 22 リスト管理(&L) - Fill - MS UI Gothic, 9pt, style=Bold - Off - 59, 3 - 3, 3, 3, 0 - 340, 14 - 1 - LblName - MiddleLeft 発言本文 Fill 59, 20 @@ -171,6 +187,16 @@ 再読み込み(&R) 231, 22 フォロー解除(&N) + Bottom + True + MS UI Gothic, 9pt, style=Bold + NoControl + 141, 3 + 3, 3, 0, 0 + 141, 12 + 1 + RetweetedByLinkLabel + MiddleLeft 231, 22 保存(&I)... 231, 22 @@ -218,7 +244,7 @@ 4 Fill - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="UserPicture" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="NameLabel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="PostBrowser" Row="1" RowSpan="1" Column="1" ColumnSpan="3" /><Control Name="DateTimeLabel" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="SourceLinkLabel" Row="0" RowSpan="1" Column="3" ColumnSpan="1" /></Controls><Columns Styles="Absolute,56,Percent,100,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0,Percent,100" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="UserPicture" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="flowLayoutPanel1" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="PostBrowser" Row="1" RowSpan="1" Column="1" ColumnSpan="3" /><Control Name="DateTimeLabel" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="SourceLinkLabel" Row="0" RowSpan="1" Column="3" ColumnSpan="1" /></Controls><Columns Styles="Absolute,56,Percent,100,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0,Percent,100" /></TableLayoutSettings> 0, 0 2 511, 85 From b04f65ff206f587d65fb04174e3415477d061ecf Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 26 Mar 2022 22:33:57 +0900 Subject: [PATCH 120/402] =?UTF-8?q?=E7=AD=89=E5=B9=85=E3=83=95=E3=82=A9?= =?UTF-8?q?=E3=83=B3=E3=83=88=E8=A1=A8=E7=A4=BA=E3=82=92=E6=9C=89=E5=8A=B9?= =?UTF-8?q?=E3=81=AB=E3=81=97=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AB=E8=83=8C?= =?UTF-8?q?=E6=99=AF=E8=89=B2=E3=81=AE=E8=A8=AD=E5=AE=9A=E3=81=8C=E5=85=A8?= =?UTF-8?q?=E9=9D=A2=E3=81=AB=E9=81=A9=E7=94=A8=E3=81=95=E3=82=8C=E3=81=AA?= =?UTF-8?q?=E3=81=84=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=20(thx=20@StoutAmmo!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://twitter.com/StoutAmmo/status/1490698422113865734 Fixes: 741290c4 ("発言詳細部のCSSを整理") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 59 +++++++++++-------------------- 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 3226ecc35..bbe69f22e 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -6,6 +6,7 @@ * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) + * FIX: 等幅フォント表示を有効にした場合に背景色の設定が全面に適用されない不具合を修正 (thx @StoutAmmo!) ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 80250ba2c..26ab7b172 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -105,37 +105,27 @@ public partial class TweenMain : OTBaseForm private readonly object syncObject = new object(); // ロック用 - private const string DetailHtmlFormatHeaderMono = - "" + private const string DetailHtmlFormatHead = + "" + "" - + "
";
+            + "";
 
-        private const string DetailHtmlFormatFooterMono = "
"; + private const string DetailHtmlFormatTemplateMono = + "" + DetailHtmlFormatHead + "
%CONTENT_HTML%
"; - private const string DetailHtmlFormatHeaderColor = - "" - + "" - + "

"; + private const string DetailHtmlFormatTemplateNormal = + "" + DetailHtmlFormatHead + "

%CONTENT_HTML%

"; - private const string DetailHtmlFormatFooterColor = "

"; - private string detailHtmlFormatHeader = null!; - private string detailHtmlFormatFooter = null!; + private string detailHtmlFormatPreparedTemplate = null!; private bool myStatusError = false; private bool myStatusOnline = false; @@ -1236,24 +1226,15 @@ private void TweenMain_Load(object sender, EventArgs e) private void InitDetailHtmlFormat() { - if (SettingManager.Common.IsMonospace) - { - this.detailHtmlFormatHeader = DetailHtmlFormatHeaderMono; - this.detailHtmlFormatFooter = DetailHtmlFormatFooterMono; - } - else - { - this.detailHtmlFormatHeader = DetailHtmlFormatHeaderColor; - this.detailHtmlFormatFooter = DetailHtmlFormatFooterColor; - } + var htmlTemplate = SettingManager.Common.IsMonospace ? DetailHtmlFormatTemplateMono : DetailHtmlFormatTemplateNormal; - this.detailHtmlFormatHeader = this.detailHtmlFormatHeader - .Replace("%FONT_FAMILY%", this.fntDetail.Name) - .Replace("%FONT_SIZE%", this.fntDetail.Size.ToString()) - .Replace("%FONT_COLOR%", $"{this.clDetail.R},{this.clDetail.G},{this.clDetail.B}") - .Replace("%LINK_COLOR%", $"{this.clDetailLink.R},{this.clDetailLink.G},{this.clDetailLink.B}") - .Replace("%BG_COLOR%", $"{this.clDetailBackcolor.R},{this.clDetailBackcolor.G},{this.clDetailBackcolor.B}") - .Replace("%BG_REPLY_COLOR%", $"{this.clAtTo.R}, {this.clAtTo.G}, {this.clAtTo.B}"); + this.detailHtmlFormatPreparedTemplate = htmlTemplate + .Replace("%FONT_FAMILY%", this.fntDetail.Name) + .Replace("%FONT_SIZE%", this.fntDetail.Size.ToString()) + .Replace("%FONT_COLOR%", $"{this.clDetail.R},{this.clDetail.G},{this.clDetail.B}") + .Replace("%LINK_COLOR%", $"{this.clDetailLink.R},{this.clDetailLink.G},{this.clDetailLink.B}") + .Replace("%BG_COLOR%", $"{this.clDetailBackcolor.R},{this.clDetailBackcolor.G},{this.clDetailBackcolor.B}") + .Replace("%BG_REPLY_COLOR%", $"{this.clAtTo.R}, {this.clAtTo.G}, {this.clAtTo.B}"); } private void ListTab_DrawItem(object sender, DrawItemEventArgs e) @@ -5528,7 +5509,7 @@ private void UpdateSelectedPost() } public string CreateDetailHtml(string orgdata) - => this.detailHtmlFormatHeader + orgdata + this.detailHtmlFormatFooter; + => this.detailHtmlFormatPreparedTemplate.Replace("%CONTENT_HTML%", orgdata); private void DispSelectedPost() => this.DispSelectedPost(false); From 3055424290d6cf40df4e3b89a0a5ac88580ab147 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 26 Mar 2022 23:07:58 +0900 Subject: [PATCH 121/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E8=A9=B3=E7=B4=B0?= =?UTF-8?q?=E6=AC=84=E3=81=AE=E8=83=8C=E6=99=AF=E8=89=B2=E3=82=92WebBrowse?= =?UTF-8?q?r=E5=88=9D=E6=9C=9F=E5=8C=96=E7=9B=B4=E5=BE=8C=E3=81=AE?= =?UTF-8?q?=E7=8A=B6=E6=85=8B=E3=81=8B=E3=82=89=E9=81=A9=E7=94=A8=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 1 + OpenTween/TweetDetailsView.cs | 3 +++ OpenTween/UserInfoDialog.cs | 4 ++-- 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index bbe69f22e..5eb3cb176 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -7,6 +7,7 @@ * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) * FIX: 等幅フォント表示を有効にした場合に背景色の設定が全面に適用されない不具合を修正 (thx @StoutAmmo!) + * FIX: 起動直後の時点で発言詳細欄の背景色設定が適用されていない不具合を修正 ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 26ab7b172..9fd63453a 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -993,6 +993,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.sfTab.LineAlignment = StringAlignment.Center; this.InitDetailHtmlFormat(); + this.tweetDetailsView.ClearPostBrowser(); this.recommendedStatusFooter = " [TWNv" + Regex.Replace(MyCommon.FileVersion.Replace(".", ""), "^0*", "") + "]"; diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 7032abb2d..b8caaed49 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -87,6 +87,9 @@ public TweetDetailsView() this.PostBrowser.AllowWebBrowserDrop = false; // COMException を回避するため、ActiveX の初期化が終わってから設定する } + public void ClearPostBrowser() + => this.PostBrowser.DocumentText = this.Owner.CreateDetailHtml(""); + public async Task ShowPostDetails(PostClass post) { this.CurrentPost = post; diff --git a/OpenTween/UserInfoDialog.cs b/OpenTween/UserInfoDialog.cs index 826f40532..9996e05a3 100644 --- a/OpenTween/UserInfoDialog.cs +++ b/OpenTween/UserInfoDialog.cs @@ -187,7 +187,7 @@ private async Task SetDescriptionAsync(string? descriptionText, TwitterEntities? } else { - this.DescriptionBrowser.DocumentText = ""; + this.DescriptionBrowser.DocumentText = this.mainForm.CreateDetailHtml(""); } } @@ -268,7 +268,7 @@ private async Task SetRecentStatusAsync(TwitterStatus? status, CancellationToken } else { - this.RecentPostBrowser.DocumentText = Properties.Resources.ShowUserInfo2; + this.RecentPostBrowser.DocumentText = this.mainForm.CreateDetailHtml(Properties.Resources.ShowUserInfo2); } } From 0626b8492c98f4ff0b19970196df48636ea8f0a0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 01:11:29 +0900 Subject: [PATCH 122/402] =?UTF-8?q?=E3=82=AF=E3=83=AA=E3=83=83=E3=83=97?= =?UTF-8?q?=E3=83=9C=E3=83=BC=E3=83=89=E7=B5=8C=E7=94=B1=E3=81=A7=E3=81=AE?= =?UTF-8?q?=E8=A4=87=E6=95=B0=E6=9E=9A=E3=81=AE=E7=94=BB=E5=83=8F=E3=83=95?= =?UTF-8?q?=E3=82=A1=E3=82=A4=E3=83=AB=E6=B7=BB=E4=BB=98=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 5eb3cb176..53073600d 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -3,6 +3,7 @@ ==== Ver 2.5.1-dev(2022/xx/xx) * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) * NEW: 発言詳細欄の名前やアイコンのクリックによるプロフィール表示に対応 + * NEW: クリップボード経由での複数枚の画像ファイル添付に対応 * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 9fd63453a..45cf5eb3b 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -10866,6 +10866,11 @@ private void ProcClipboardFromStatusTextWhenCtrlPlusV() this.ImageSelector.BeginSelection(image); } } + else if (Clipboard.ContainsFileDropList()) + { + var files = Clipboard.GetFileDropList().Cast().ToArray(); + this.ImageSelector.BeginSelection(files); + } } catch (ExternalException ex) { From 5d0f7ec80fec3bd75360e5eee23e7aa14871b4f9 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 02:07:14 +0900 Subject: [PATCH 123/402] =?UTF-8?q?=E3=83=97=E3=83=AD=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E7=94=BB=E5=83=8FURL=E3=81=AE=E7=94=9F?= =?UTF-8?q?=E6=88=90=E3=82=92=20Twitter.CreateProfileImageUrl=20=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TwitterTest.cs | 13 +++++++++++++ OpenTween/ListManage.cs | 2 +- OpenTween/TweetDetailsView.cs | 7 ++++--- OpenTween/Twitter.cs | 22 ++++++++++++++++++++++ OpenTween/UserInfoDialog.cs | 4 ++-- 5 files changed, 42 insertions(+), 6 deletions(-) diff --git a/OpenTween.Tests/TwitterTest.cs b/OpenTween.Tests/TwitterTest.cs index b1e4890af..431d19ef4 100644 --- a/OpenTween.Tests/TwitterTest.cs +++ b/OpenTween.Tests/TwitterTest.cs @@ -645,5 +645,18 @@ public void GetTextLengthRemain_BrokenSurrogateTest() Assert.Equal(278, twitter.GetTextLengthRemain("\ud83d")); Assert.Equal(9999, twitter.GetTextLengthRemain("D twitter \ud83d")); } + + [Theory] + [InlineData("https://pbs.twimg.com/profile_images/00000/foo_normal.jpg", "normal", "https://pbs.twimg.com/profile_images/00000/foo_normal.jpg")] + [InlineData("https://pbs.twimg.com/profile_images/00000/foo_normal.jpg", "bigger", "https://pbs.twimg.com/profile_images/00000/foo_bigger.jpg")] + [InlineData("https://pbs.twimg.com/profile_images/00000/foo_normal.jpg", "mini", "https://pbs.twimg.com/profile_images/00000/foo_mini.jpg")] + [InlineData("https://pbs.twimg.com/profile_images/00000/foo_normal.jpg", "original", "https://pbs.twimg.com/profile_images/00000/foo.jpg")] + [InlineData("https://pbs.twimg.com/profile_images/00000/foo_normal_bar_normal.jpg", "original", "https://pbs.twimg.com/profile_images/00000/foo_normal_bar.jpg")] + public void CreateProfileImageUrl_Test(string normalUrl, string size, string expected) + => Assert.Equal(expected, Twitter.CreateProfileImageUrl(normalUrl, size)); + + [Fact] + public void CreateProfileImageUrl_InvalidSizeTest() + => Assert.Throws(() => Twitter.CreateProfileImageUrl("https://pbs.twimg.com/profile_images/00000/foo_normal.jpg", "INVALID")); } } diff --git a/OpenTween/ListManage.cs b/OpenTween/ListManage.cs index 0817c432b..0e725bb3b 100644 --- a/OpenTween/ListManage.cs +++ b/OpenTween/ListManage.cs @@ -349,7 +349,7 @@ private async Task LoadUserIconAsync(Uri imageUri, long userId) await this.UserIcon.SetImageFromTask(async () => { - var uri = imageUri.AbsoluteUri.Replace("_normal", "_bigger"); + var uri = Twitter.CreateProfileImageUrl(imageUri.AbsoluteUri, "bigger"); using var imageStream = await Networking.Http.GetStreamAsync(uri); var image = await MemoryImage.CopyFromStreamAsync(imageStream); diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index b8caaed49..b50721ff0 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -701,11 +701,12 @@ private void SearchAtPostsDetailNameToolStripMenuItem_Click(object sender, Event private async void IconNameToolStripMenuItem_Click(object sender, EventArgs e) { - var imageUrl = this.CurrentPost?.ImageUrl; - if (MyCommon.IsNullOrEmpty(imageUrl)) + var imageNormalUrl = this.CurrentPost?.ImageUrl; + if (MyCommon.IsNullOrEmpty(imageNormalUrl)) return; - await MyCommon.OpenInBrowserAsync(this, imageUrl.Remove(imageUrl.LastIndexOf("_normal", StringComparison.Ordinal), 7)); // "_normal".Length + var imageOriginalUrl = Twitter.CreateProfileImageUrl(imageNormalUrl, "original"); + await MyCommon.OpenInBrowserAsync(this, imageOriginalUrl); } private async void ReloadIconToolStripMenuItem_Click(object sender, EventArgs e) diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 6638b1e35..eb30af22b 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1780,6 +1780,28 @@ int GetWeightFromCodepoint(int codepoint) return remainWeight / config.Scale; } + /// + /// プロフィール画像のサイズを指定したURLを生成 + /// + /// + /// https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/user-profile-images-and-banners を参照 + /// + public static string CreateProfileImageUrl(string normalUrl, string size) + { + switch (size) + { + case "original": + return normalUrl.Replace("_normal.", "."); + case "normal": + return normalUrl; + case "bigger": + case "mini": + return normalUrl.Replace("_normal.", $"_{size}."); + default: + throw new ArgumentException($"Invalid size: ${size}", nameof(size)); + } + } + public bool IsDisposed { get; private set; } = false; protected virtual void Dispose(bool disposing) diff --git a/OpenTween/UserInfoDialog.cs b/OpenTween/UserInfoDialog.cs index 9996e05a3..15d273ef8 100644 --- a/OpenTween/UserInfoDialog.cs +++ b/OpenTween/UserInfoDialog.cs @@ -204,7 +204,7 @@ private async Task SetUserImageAsync(string imageUri, CancellationToken cancella await this.UserPicture.SetImageFromTask(async () => { - var uri = imageUri.Replace("_normal", "_bigger"); + var uri = Twitter.CreateProfileImageUrl(imageUri, "bigger"); using var imageStream = await Networking.Http.GetStreamAsync(uri) .ConfigureAwait(false); @@ -464,7 +464,7 @@ private async void ButtonSearchPosts_Click(object sender, EventArgs e) private async void UserPicture_Click(object sender, EventArgs e) { var imageUrl = this.displayUser.ProfileImageUrlHttps; - imageUrl = imageUrl.Remove(imageUrl.LastIndexOf("_normal", StringComparison.Ordinal), 7); + imageUrl = Twitter.CreateProfileImageUrl(imageUrl, "original"); await MyCommon.OpenInBrowserAsync(this, imageUrl); } From 025e400b7186a74f2203a8f29815066d91f20621 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 03:48:15 +0900 Subject: [PATCH 124/402] =?UTF-8?q?=E7=94=BB=E9=9D=A2=E4=B8=8A=E3=81=AB?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B=E8=A7=A3=E5=83=8F=E5=BA=A6?= =?UTF-8?q?=E3=81=AB=E5=BF=9C=E3=81=98=E3=81=9F=E3=83=97=E3=83=AD=E3=83=95?= =?UTF-8?q?=E3=82=A3=E3=83=BC=E3=83=AB=E7=94=BB=E5=83=8F=E3=81=AE=E5=8F=96?= =?UTF-8?q?=E5=BE=97=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TwitterTest.cs | 10 +++++++++ OpenTween/ImageCache.cs | 16 +++++++++++++++ OpenTween/ImageListViewItem.cs | 20 ++++++++++++++---- OpenTween/ListManage.cs | 3 ++- OpenTween/OTPictureBox.cs | 7 ++++--- OpenTween/Resources/ChangeLog.txt | 3 +++ OpenTween/Tween.cs | 9 ++++++-- OpenTween/TweetDetailsView.cs | 34 +++++++++++++++++++++++-------- OpenTween/Twitter.cs | 12 +++++++++++ OpenTween/UserInfoDialog.cs | 3 ++- 10 files changed, 98 insertions(+), 19 deletions(-) diff --git a/OpenTween.Tests/TwitterTest.cs b/OpenTween.Tests/TwitterTest.cs index 431d19ef4..5fac92890 100644 --- a/OpenTween.Tests/TwitterTest.cs +++ b/OpenTween.Tests/TwitterTest.cs @@ -658,5 +658,15 @@ public void CreateProfileImageUrl_Test(string normalUrl, string size, string exp [Fact] public void CreateProfileImageUrl_InvalidSizeTest() => Assert.Throws(() => Twitter.CreateProfileImageUrl("https://pbs.twimg.com/profile_images/00000/foo_normal.jpg", "INVALID")); + + [Theory] + [InlineData(24, "mini")] + [InlineData(25, "normal")] + [InlineData(48, "normal")] + [InlineData(49, "bigger")] + [InlineData(73, "bigger")] + [InlineData(74, "original")] + public void DecideProfileImageSize_Test(int sizePx, string expected) + => Assert.Equal(expected, Twitter.DecideProfileImageSize(sizePx)); } } diff --git a/OpenTween/ImageCache.cs b/OpenTween/ImageCache.cs index 1789ffbf5..8b98b8d25 100644 --- a/OpenTween/ImageCache.cs +++ b/OpenTween/ImageCache.cs @@ -140,6 +140,22 @@ private async Task FetchImageAsync(string uri, CancellationToken ca } } + public MemoryImage? TryGetLargerOrSameSizeFromCache(string normalUrl, string size) + { + var sizes = new[] { "mini", "normal", "bigger", "original" }; + var minimumIndex = sizes.FindIndex(x => x == size); + + foreach (var candidateSize in sizes.Skip(minimumIndex)) + { + var imageUrl = Twitter.CreateProfileImageUrl(normalUrl, candidateSize); + var image = this.TryGetFromCache(imageUrl); + if (image != null) + return image; + } + + return null; + } + public void CancelAsync() { lock (this.lockObject) diff --git a/OpenTween/ImageListViewItem.cs b/OpenTween/ImageListViewItem.cs index 9d8c41d4c..74d2335d2 100644 --- a/OpenTween/ImageListViewItem.cs +++ b/OpenTween/ImageListViewItem.cs @@ -54,18 +54,18 @@ public class ImageListViewItem : ListViewItem public event EventHandler? ImageDownloaded; public ImageListViewItem(string[] items) - : this(items, null, null) + : this(items, null, null, 0) { } - public ImageListViewItem(string[] items, ImageCache? imageCache, string? imageUrl) + public ImageListViewItem(string[] items, ImageCache? imageCache, string? imageNormalUrl, int imageSize) : base(items) { this.imageCache = imageCache; - this.imageUrl = imageUrl; + this.imageUrl = this.CreateImageUrl(imageNormalUrl, imageSize); this.StateIndex = -1; - var image = imageUrl != null ? imageCache?.TryGetFromCache(imageUrl) : null; + var image = this.imageUrl != null ? imageCache?.TryGetFromCache(this.imageUrl) : null; if (image != null) this.imageReference.Target = image; @@ -76,6 +76,18 @@ protected ImageListViewItem(SerializationInfo info, StreamingContext context) { } + private string? CreateImageUrl(string? normalImageUrl, int imageSize) + { + if (MyCommon.IsNullOrEmpty(normalImageUrl)) + return null; + + if (imageSize <= 0) + return null; + + var sizeName = Twitter.DecideProfileImageSize(imageSize); + return Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); + } + public Task GetImageAsync(bool force = false) { if (this.imageTask == null || this.imageTask.IsCompleted) diff --git a/OpenTween/ListManage.cs b/OpenTween/ListManage.cs index 0e725bb3b..f3723e6b4 100644 --- a/OpenTween/ListManage.cs +++ b/OpenTween/ListManage.cs @@ -349,7 +349,8 @@ private async Task LoadUserIconAsync(Uri imageUri, long userId) await this.UserIcon.SetImageFromTask(async () => { - var uri = Twitter.CreateProfileImageUrl(imageUri.AbsoluteUri, "bigger"); + var sizeName = Twitter.DecideProfileImageSize(this.UserIcon.Width); + var uri = Twitter.CreateProfileImageUrl(imageUri.AbsoluteUri, sizeName); using var imageStream = await Networking.Http.GetStreamAsync(uri); var image = await MemoryImage.CopyFromStreamAsync(imageStream); diff --git a/OpenTween/OTPictureBox.cs b/OpenTween/OTPictureBox.cs index 92b9a330b..5ebb65140 100644 --- a/OpenTween/OTPictureBox.cs +++ b/OpenTween/OTPictureBox.cs @@ -103,13 +103,14 @@ private void RestoreSizeMode() ///
private int currentImageTaskId = 0; - public async Task SetImageFromTask(Func> imageTask) + public async Task SetImageFromTask(Func> imageTask, bool useStatusImage = true) { var id = Interlocked.Increment(ref this.currentImageTaskId); try { - this.ShowInitialImage(); + if (useStatusImage) + this.ShowInitialImage(); var image = await imageTask(); @@ -118,7 +119,7 @@ public async Task SetImageFromTask(Func> imageTask) } catch (Exception) { - if (id == this.currentImageTaskId) + if (id == this.currentImageTaskId && useStatusImage) this.ShowErrorImage(); try { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 53073600d..a36868cf0 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -4,6 +4,9 @@ * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) * NEW: 発言詳細欄の名前やアイコンのクリックによるプロフィール表示に対応 * NEW: クリップボード経由での複数枚の画像ファイル添付に対応 + * NEW: 画面上に表示する解像度に応じたプロフィール画像の取得に対応 + - 高DPI環境で表示した場合により高解像度のプロフィール画像が取得されるようになります + - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 45cf5eb3b..4e0abdf33 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -3751,6 +3751,8 @@ private void ApplyListViewIconSize(MyCommon.IconSizes iconSz) }; this.iconCol = iconSz == MyCommon.IconSizes.Icon48_2; + this.PurgeListViewItemCache(); + if (this.iconSz > 0) { // ディスプレイの DPI 設定を考慮したサイズを設定する @@ -4731,6 +4733,9 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) var mk = new StringBuilder(); if (post.FavoritedCount > 0) mk.Append("+" + post.FavoritedCount); + + var scaledIconSz = (int)Math.Ceiling(this.iconSz * this.CurrentScaleFactor.Width); + ImageListViewItem itm; if (post.RetweetedId == null) { @@ -4745,7 +4750,7 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) mk.ToString(), post.Source, }; - itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl); + itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl, scaledIconSz); } else { @@ -4760,7 +4765,7 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) mk.ToString(), post.Source, }; - itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl); + itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl, scaledIconSz); } itm.StateIndex = post.StateIndex; itm.Tag = post; diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index b50721ff0..4527fb4b5 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -247,9 +247,9 @@ public HtmlElement[] GetLinkElements() .ToArray(); } - private async Task SetUserPictureAsync(string imageUrl, bool force = false) + private async Task SetUserPictureAsync(string normalImageUrl, bool force = false) { - if (MyCommon.IsNullOrEmpty(imageUrl)) + if (MyCommon.IsNullOrEmpty(normalImageUrl)) return; if (this.IconCache == null) @@ -257,14 +257,32 @@ private async Task SetUserPictureAsync(string imageUrl, bool force = false) this.ClearUserPicture(); - await this.UserPicture.SetImageFromTask(async () => + var imageSize = Twitter.DecideProfileImageSize(this.UserPicture.Width); + var cachedImage = this.IconCache.TryGetLargerOrSameSizeFromCache(normalImageUrl, imageSize); + if (cachedImage != null) { - var image = await this.IconCache.DownloadImageAsync(imageUrl, force) - .ConfigureAwait(false); + // 既にキャッシュされていればそれを表示して終了 + this.UserPicture.Image = cachedImage.Clone(); + return; + } + + // 小さいサイズの画像がキャッシュにある場合は高解像度の画像が取得できるまでの間表示する + var fallbackImage = this.IconCache.TryGetLargerOrSameSizeFromCache(normalImageUrl, "mini"); + if (fallbackImage != null) + this.UserPicture.Image = fallbackImage.Clone(); - return await image.CloneAsync() - .ConfigureAwait(false); - }); + await this.UserPicture.SetImageFromTask( + async () => + { + var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, imageSize); + var image = await this.IconCache.DownloadImageAsync(imageUrl, force) + .ConfigureAwait(false); + + return await image.CloneAsync() + .ConfigureAwait(false); + }, + useStatusImage: false + ); } /// diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index eb30af22b..2ee470005 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1802,6 +1802,18 @@ public static string CreateProfileImageUrl(string normalUrl, string size) } } + public static string DecideProfileImageSize(int sizePx) + { + if (sizePx <= 24) + return "mini"; + else if (sizePx <= 48) + return "normal"; + else if (sizePx <= 73) + return "bigger"; + else + return "original"; + } + public bool IsDisposed { get; private set; } = false; protected virtual void Dispose(bool disposing) diff --git a/OpenTween/UserInfoDialog.cs b/OpenTween/UserInfoDialog.cs index 15d273ef8..ac778d17f 100644 --- a/OpenTween/UserInfoDialog.cs +++ b/OpenTween/UserInfoDialog.cs @@ -204,7 +204,8 @@ private async Task SetUserImageAsync(string imageUri, CancellationToken cancella await this.UserPicture.SetImageFromTask(async () => { - var uri = Twitter.CreateProfileImageUrl(imageUri, "bigger"); + var sizeName = Twitter.DecideProfileImageSize(this.UserPicture.Width); + var uri = Twitter.CreateProfileImageUrl(imageUri, sizeName); using var imageStream = await Networking.Http.GetStreamAsync(uri) .ConfigureAwait(false); From 4a744e8b294e3ff3bcdd03a69eb223969e744b7e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 06:46:34 +0900 Subject: [PATCH 125/402] =?UTF-8?q?=E3=83=AA=E3=83=97=E3=83=A9=E3=82=A4?= =?UTF-8?q?=E6=99=82=E3=81=AB=E6=8A=95=E7=A8=BF=E6=AC=84=E3=81=AB=E5=85=A5?= =?UTF-8?q?=E5=8A=9B=E3=81=99=E3=82=8B=E3=83=86=E3=82=AD=E3=82=B9=E3=83=88?= =?UTF-8?q?=E3=81=AE=E7=94=9F=E6=88=90=E5=87=A6=E7=90=86=E3=82=92=E6=95=B4?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 3 + OpenTween/Tween.cs | 303 +++++++----------------------- 2 files changed, 68 insertions(+), 238 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index a36868cf0..d4296ed6b 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -8,10 +8,13 @@ - 高DPI環境で表示した場合により高解像度のプロフィール画像が取得されるようになります - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 + * CHG: DMが選択されている時は「@返信」「@返信ALL」のどちらも「DM送信」と同じ動作となるように変更 + * CHG: 複数のユーザー宛のリプライ時にツイートの先頭にピリオドを加える仕様を廃止 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) * FIX: 等幅フォント表示を有効にした場合に背景色の設定が全面に適用されない不具合を修正 (thx @StoutAmmo!) * FIX: 起動直後の時点で発言詳細欄の背景色設定が適用されていない不具合を修正 + * FIX: 自分のツイートに対する「@返信ALL」で自分宛のMentionが付かない不具合を修正 (thx @doug_lee42!) ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 4e0abdf33..fa763adb4 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2885,7 +2885,7 @@ private async void MyList_MouseDoubleClick(object sender, MouseEventArgs e) switch (SettingManager.Common.ListDoubleClickAction) { case 0: - this.MakeReplyOrDirectStatus(); + this.MakeReplyText(); break; case 1: await this.FavoriteChange(true); @@ -3230,10 +3230,10 @@ private void ContextMenuOperate_Opening(object sender, CancelEventArgs e) } private void ReplyStripMenuItem_Click(object sender, EventArgs e) - => this.MakeReplyOrDirectStatus(false, true); + => this.MakeReplyText(); private void DMStripMenuItem_Click(object sender, EventArgs e) - => this.MakeReplyOrDirectStatus(false, false); + => this.MakeDirectMessageText(); private async Task DoStatusDelete() { @@ -5676,7 +5676,7 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Enter) .FocusedOn(FocusedControl.ListTab) - .Do(() => this.MakeReplyOrDirectStatus()), + .Do(() => this.MakeReplyText()), ShortcutCommand.Create(Keys.R) .FocusedOn(FocusedControl.ListTab) @@ -5765,13 +5765,13 @@ private void InitializeShortcuts() .Do(() => { }), ShortcutCommand.Create(Keys.Control | Keys.R) - .Do(() => this.MakeReplyOrDirectStatus(isAuto: false, isReply: true)), + .Do(() => this.MakeReplyText()), ShortcutCommand.Create(Keys.Control | Keys.D) .Do(() => this.DoStatusDelete()), ShortcutCommand.Create(Keys.Control | Keys.M) - .Do(() => this.MakeReplyOrDirectStatus(isAuto: false, isReply: false)), + .Do(() => this.MakeDirectMessageText()), ShortcutCommand.Create(Keys.Control | Keys.S) .Do(() => this.FavoriteChange(favAdd: true)), @@ -6014,7 +6014,7 @@ private void InitializeShortcuts() .Do(() => this.GoSamePostToAnotherTab(left: true)), ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.R) - .Do(() => this.MakeReplyOrDirectStatus(isAuto: false, isReply: true, isAll: true)), + .Do(() => this.MakeReplyText(atAll: true)), ShortcutCommand.Create(Keys.Control | Keys.Shift | Keys.C, Keys.Control | Keys.Shift | Keys.Insert) .Do(() => this.CopyIdUri()), @@ -7408,250 +7408,77 @@ public void ReOrderTab(string targetTabText, string baseTabText, bool isBeforeBa this.SaveConfigsTabs(); } - private void MakeReplyOrDirectStatus(bool isAuto = true, bool isReply = true, bool isAll = false) + private void MakeDirectMessageText() { - // isAuto:true=先頭に挿入、false=カーソル位置に挿入 - // isReply:true=@,false=DM - if (!this.StatusText.Enabled) return; - if (!this.ExistCurrentPost) return; + var selectedPosts = this.CurrentTab.SelectedPosts; + if (selectedPosts.Length > 1) + return; - var tab = this.CurrentTab; - var selectedPosts = tab.SelectedPosts; + var post = selectedPosts.Single(); + var text = $"D {post.ScreenName} {this.StatusText.Text}"; - // 複数あてリプライはReplyではなく通常ポスト - // ↑仕様変更で全部リプライ扱いでOK(先頭ドット付加しない) - // 090403暫定でドットを付加しないようにだけ修正。単独と複数の処理は統合できると思われる。 - // 090513 all @ replies 廃止の仕様変更によりドット付加に戻し(syo68k) + this.inReplyTo = null; + this.StatusText.Text = text; + this.StatusText.SelectionStart = text.Length; + this.StatusText.Focus(); + } - if (selectedPosts.Length > 0) + private void MakeReplyText(bool atAll = false) + { + var selectedPosts = this.CurrentTab.SelectedPosts; + if (selectedPosts.Any(x => x.IsDm)) { - // アイテムが1件以上選択されている - if (selectedPosts.Length == 1 && !isAll && this.ExistCurrentPost) - { - var post = selectedPosts.Single(); + this.MakeDirectMessageText(); + return; + } - // 単独ユーザー宛リプライまたはDM - if ((tab.TabType == MyCommon.TabUsageType.DirectMessage && isAuto) || (!isAuto && !isReply)) - { - // ダイレクトメッセージ - this.inReplyTo = null; - this.StatusText.Text = "D " + post.ScreenName + " " + this.StatusText.Text; - this.StatusText.SelectionStart = this.StatusText.Text.Length; - this.StatusText.Focus(); - return; - } - if (MyCommon.IsNullOrEmpty(this.StatusText.Text)) - { - // 空の場合 - var inReplyToStatusId = post.RetweetedId ?? post.StatusId; - var inReplyToScreenName = post.ScreenName; - this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); + if (selectedPosts.Length == 1) + { + var post = selectedPosts.Single(); + var inReplyToStatusId = post.RetweetedId ?? post.StatusId; + var inReplyToScreenName = post.ScreenName; + this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); + } + else + { + this.inReplyTo = null; + } - // ステータステキストが入力されていない場合先頭に@ユーザー名を追加する - this.StatusText.Text = "@" + post.ScreenName + " "; - } - else - { - // 何か入力済の場合 + var selfScreenName = this.tw.Username; + var targetScreenNames = new List(); + foreach (var post in selectedPosts) + { + if (post.ScreenName != selfScreenName) + targetScreenNames.Add(post.ScreenName); - if (isAuto) - { - // 1件選んでEnter or DoubleClick - if (this.StatusText.Text.Contains("@" + post.ScreenName + " ")) - { - if (this.inReplyTo?.ScreenName == post.ScreenName) - { - // 返信先書き換え - var inReplyToStatusId = post.RetweetedId ?? post.StatusId; - var inReplyToScreenName = post.ScreenName; - this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); - } - return; - } - if (!this.StatusText.Text.StartsWith("@", StringComparison.Ordinal)) - { - // 文頭@以外 - if (this.StatusText.Text.StartsWith(". ", StringComparison.Ordinal)) - { - // 複数リプライ - this.inReplyTo = null; - this.StatusText.Text = this.StatusText.Text.Insert(2, "@" + post.ScreenName + " "); - } - else - { - // 単独リプライ - var inReplyToStatusId = post.RetweetedId ?? post.StatusId; - var inReplyToScreenName = post.ScreenName; - this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); - this.StatusText.Text = "@" + post.ScreenName + " " + this.StatusText.Text; - } - } - else - { - // 文頭@ - // 複数リプライ - this.inReplyTo = null; - this.StatusText.Text = ". @" + post.ScreenName + " " + this.StatusText.Text; - } - } - else - { - // 1件選んでCtrl-Rの場合(返信先操作せず) - var sidx = this.StatusText.SelectionStart; - var id = "@" + post.ScreenName + " "; - if (sidx > 0) - { - if (this.StatusText.Text.Substring(sidx - 1, 1) != " ") - { - id = " " + id; - } - } - this.StatusText.Text = this.StatusText.Text.Insert(sidx, id); - sidx += id.Length; - this.StatusText.SelectionStart = sidx; - this.StatusText.Focus(); - return; - } - } - } - else + if (atAll) { - // 複数リプライ - if (!isAuto && !isReply) return; - - // C-S-rか、複数の宛先を選択中にEnter/DoubleClick/C-r/C-S-r - - if (isAuto) + foreach (var (_, screenName) in post.ReplyToList) { - // Enter or DoubleClick - - var sTxt = this.StatusText.Text; - if (!sTxt.StartsWith(". ", StringComparison.Ordinal)) - { - sTxt = ". " + sTxt; - this.inReplyTo = null; - } - foreach (var post in selectedPosts) - { - if (!sTxt.Contains("@" + post.ScreenName + " ")) - sTxt = sTxt.Insert(2, "@" + post.ScreenName + " "); - } - this.StatusText.Text = sTxt; + if (screenName != selfScreenName) + targetScreenNames.Add(screenName); } - else - { - // C-S-r or C-r - - if (selectedPosts.Length > 1) - { - // 複数ポスト選択 - - var ids = ""; - var sidx = this.StatusText.SelectionStart; - foreach (var post in selectedPosts) - { - if (!ids.Contains("@" + post.ScreenName + " ") && post.UserId != this.tw.UserId) - { - ids += "@" + post.ScreenName + " "; - } - if (isAll) - { - foreach (var (_, screenName) in post.ReplyToList) - { - if (!ids.Contains("@" + screenName + " ") && - !screenName.Equals(this.tw.Username, StringComparison.CurrentCultureIgnoreCase)) - { - var m = Regex.Match(post.TextFromApi, "[@@](?" + screenName + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase); - if (m.Success) - ids += "@" + m.Result("${id}") + " "; - else - ids += "@" + screenName + " "; - } - } - } - } - if (ids.Length == 0) return; - if (!this.StatusText.Text.StartsWith(". ", StringComparison.Ordinal)) - { - this.inReplyTo = null; - this.StatusText.Text = ". " + this.StatusText.Text; - sidx += 2; - } - if (sidx > 0) - { - if (this.StatusText.Text.Substring(sidx - 1, 1) != " ") - { - ids = " " + ids; - } - } - this.StatusText.Text = this.StatusText.Text.Insert(sidx, ids); - sidx += ids.Length; - this.StatusText.SelectionStart = sidx; - this.StatusText.Focus(); - return; - } - else - { - // 1件のみ選択のC-S-r(返信元付加する可能性あり) + } + } - var ids = ""; - var sidx = this.StatusText.SelectionStart; - var post = selectedPosts.Single(); - if (!ids.Contains("@" + post.ScreenName + " ") && post.UserId != this.tw.UserId) - { - ids += "@" + post.ScreenName + " "; - } - foreach (var (_, screenName) in post.ReplyToList) - { - if (!ids.Contains("@" + screenName + " ") && - !screenName.Equals(this.tw.Username, StringComparison.CurrentCultureIgnoreCase)) - { - var m = Regex.Match(post.TextFromApi, "[@@](?" + screenName + ")([^a-zA-Z0-9]|$)", RegexOptions.IgnoreCase); - if (m.Success) - ids += "@" + m.Result("${id}") + " "; - else - ids += "@" + screenName + " "; - } - } - if (!MyCommon.IsNullOrEmpty(post.RetweetedBy)) - { - if (!ids.Contains("@" + post.RetweetedBy + " ") && post.RetweetedByUserId != this.tw.UserId) - { - ids += "@" + post.RetweetedBy + " "; - } - } - if (ids.Length == 0) return; - if (MyCommon.IsNullOrEmpty(this.StatusText.Text)) - { - // 未入力の場合のみ返信先付加 - var inReplyToStatusId = post.RetweetedId ?? post.StatusId; - var inReplyToScreenName = post.ScreenName; - this.inReplyTo = (inReplyToStatusId, inReplyToScreenName); - - this.StatusText.Text = ids; - this.StatusText.SelectionStart = ids.Length; - this.StatusText.Focus(); - return; - } + if (this.inReplyTo != null) + { + var (_, screenName) = this.inReplyTo.Value; + if (screenName == selfScreenName) + targetScreenNames.Insert(0, screenName); + } - if (sidx > 0) - { - if (this.StatusText.Text.Substring(sidx - 1, 1) != " ") - { - ids = " " + ids; - } - } - this.StatusText.Text = this.StatusText.Text.Insert(sidx, ids); - sidx += ids.Length; - this.StatusText.SelectionStart = sidx; - this.StatusText.Focus(); - return; - } - } - } - this.StatusText.SelectionStart = this.StatusText.Text.Length; - this.StatusText.Focus(); + var text = this.StatusText.Text; + foreach (var screenName in targetScreenNames.AsEnumerable().Reverse()) + { + var atText = $"@{screenName} "; + if (!text.Contains(atText)) + text = atText + text; } + + this.StatusText.Text = text; + this.StatusText.SelectionStart = text.Length; + this.StatusText.Focus(); } private void ListTab_MouseUp(object sender, MouseEventArgs e) @@ -8097,7 +7924,7 @@ protected override bool ProcessDialogKey(Keys keyData) } private void ReplyAllStripMenuItem_Click(object sender, EventArgs e) - => this.MakeReplyOrDirectStatus(false, true, true); + => this.MakeReplyText(atAll: true); private void IDRuleMenuItem_Click(object sender, EventArgs e) { From fb5fb0ad5e4c291058abbdf564def6d7f39eac40 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 06:59:13 +0900 Subject: [PATCH 126/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E4=B8=8A=E3=81=A7Enter=E3=82=AD=E3=83=BC=E3=82=92=E6=8A=BC?= =?UTF-8?q?=E3=81=97=E3=81=9F=E6=99=82=E3=81=AE=E5=8B=95=E4=BD=9C=E3=82=92?= =?UTF-8?q?=E3=83=80=E3=83=96=E3=83=AB=E3=82=AF=E3=83=AA=E3=83=83=E3=82=AF?= =?UTF-8?q?=E6=99=82=E3=81=A8=E5=90=8C=E3=81=98=E3=81=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index d4296ed6b..4bbbeaad4 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -10,6 +10,7 @@ * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * CHG: DMが選択されている時は「@返信」「@返信ALL」のどちらも「DM送信」と同じ動作となるように変更 * CHG: 複数のユーザー宛のリプライ時にツイートの先頭にピリオドを加える仕様を廃止 + * CHG: 発言一覧上でEnterキーを押した時の動作をダブルクリック時と同じとなるように変更 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) * FIX: 等幅フォント表示を有効にした場合に背景色の設定が全面に適用されない不具合を修正 (thx @StoutAmmo!) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index fa763adb4..52ef31222 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2881,6 +2881,9 @@ private void NotifyIcon1_MouseClick(object sender, MouseEventArgs e) } private async void MyList_MouseDoubleClick(object sender, MouseEventArgs e) + => await this.ListItemDoubleClickAction(); + + private async Task ListItemDoubleClickAction() { switch (SettingManager.Common.ListDoubleClickAction) { @@ -5676,7 +5679,7 @@ private void InitializeShortcuts() ShortcutCommand.Create(Keys.Enter) .FocusedOn(FocusedControl.ListTab) - .Do(() => this.MakeReplyText()), + .Do(() => this.ListItemDoubleClickAction()), ShortcutCommand.Create(Keys.R) .FocusedOn(FocusedControl.ListTab) From 6e13b9f1b91b32eb84c44ebd03975b0850a4253a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 07:20:24 +0900 Subject: [PATCH 127/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E3=81=AE=E3=83=80?= =?UTF-8?q?=E3=83=96=E3=83=AB=E3=82=AF=E3=83=AA=E3=83=83=E3=82=AF=E6=99=82?= =?UTF-8?q?=E3=81=AE=E5=8B=95=E4=BD=9C=E3=82=92=E5=88=97=E6=8C=99=E4=BD=93?= =?UTF-8?q?ListItemDoubleClickActionType=E3=81=A7=E5=AE=9A=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/MyCommon.cs | 13 +++++++++++ OpenTween/Setting/Panel/ActionPanel.cs | 26 +++++++++++++++++++-- OpenTween/Setting/Panel/ActionPanel.en.resx | 12 +++++----- OpenTween/Setting/Panel/ActionPanel.resx | 16 ++++++------- OpenTween/Setting/SettingCommon.cs | 12 +++++++++- OpenTween/Tween.cs | 17 +++++++------- 6 files changed, 71 insertions(+), 25 deletions(-) diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index d5657e920..1b998fb4e 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -121,6 +121,19 @@ public enum UrlConverter Twurl = -1, } + public enum ListItemDoubleClickActionType + { + // 設定ファイルの互換性を保つため新規の項目は途中に追加しないこと + Reply, + Favorite, + ShowProfile, + ShowTimeline, + ShowRelated, + OpenHomeInBrowser, + OpenStatusInBrowser, + None, + } + public enum HITRESULT { None, diff --git a/OpenTween/Setting/Panel/ActionPanel.cs b/OpenTween/Setting/Panel/ActionPanel.cs index 361c4b3cf..e5d560688 100644 --- a/OpenTween/Setting/Panel/ActionPanel.cs +++ b/OpenTween/Setting/Panel/ActionPanel.cs @@ -68,7 +68,18 @@ public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal) this.HotkeyCode.Enabled = settingCommon.HotkeyEnabled; this.CheckOpenUserTimeline.Checked = settingCommon.OpenUserTimeline; - this.ListDoubleClickActionComboBox.SelectedIndex = settingCommon.ListDoubleClickAction; + this.ListDoubleClickActionComboBox.SelectedIndex = settingCommon.ListDoubleClickAction switch + { + MyCommon.ListItemDoubleClickActionType.None => 0, + MyCommon.ListItemDoubleClickActionType.Reply => 1, + MyCommon.ListItemDoubleClickActionType.Favorite => 2, + MyCommon.ListItemDoubleClickActionType.ShowProfile => 3, + MyCommon.ListItemDoubleClickActionType.ShowTimeline => 4, + MyCommon.ListItemDoubleClickActionType.ShowRelated => 5, + MyCommon.ListItemDoubleClickActionType.OpenHomeInBrowser => 6, + MyCommon.ListItemDoubleClickActionType.OpenStatusInBrowser => 7, + _ => 1, + }; this.TabMouseLockCheck.Checked = settingCommon.TabMouseLock; } @@ -96,7 +107,18 @@ public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal) settingCommon.HotkeyKey = (Keys)this.HotkeyText.Tag; settingCommon.OpenUserTimeline = this.CheckOpenUserTimeline.Checked; - settingCommon.ListDoubleClickAction = this.ListDoubleClickActionComboBox.SelectedIndex; + settingCommon.ListDoubleClickAction = this.ListDoubleClickActionComboBox.SelectedIndex switch + { + 0 => MyCommon.ListItemDoubleClickActionType.None, + 1 => MyCommon.ListItemDoubleClickActionType.Reply, + 2 => MyCommon.ListItemDoubleClickActionType.Favorite, + 3 => MyCommon.ListItemDoubleClickActionType.ShowProfile, + 4 => MyCommon.ListItemDoubleClickActionType.ShowTimeline, + 5 => MyCommon.ListItemDoubleClickActionType.ShowRelated, + 6 => MyCommon.ListItemDoubleClickActionType.OpenHomeInBrowser, + 7 => MyCommon.ListItemDoubleClickActionType.OpenStatusInBrowser, + _ => MyCommon.ListItemDoubleClickActionType.Reply, + }; settingCommon.TabMouseLock = this.TabMouseLockCheck.Checked; } diff --git a/OpenTween/Setting/Panel/ActionPanel.en.resx b/OpenTween/Setting/Panel/ActionPanel.en.resx index 030e3596f..e885b4fed 100644 --- a/OpenTween/Setting/Panel/ActionPanel.en.resx +++ b/OpenTween/Setting/Panel/ActionPanel.en.resx @@ -29,12 +29,12 @@ Path to Browser 484, 12 Refetch tweets and verify whether marked favorites. This option causes traffic increasement. - Show user's profile - Show user's timeline - Show Relational tweet - Open user's home of twitter.com - Open status of twitter.com - Not bihavier + Do nothing + Show user's profile + Show user's timeline + Show Relational tweet + Open user's home of twitter.com + Open status of twitter.com 215, 16 Play sounds when new status arrived 157, 16 diff --git a/OpenTween/Setting/Panel/ActionPanel.resx b/OpenTween/Setting/Panel/ActionPanel.resx index 4eba03931..f9bf5b618 100644 --- a/OpenTween/Setting/Panel/ActionPanel.resx +++ b/OpenTween/Setting/Panel/ActionPanel.resx @@ -207,14 +207,14 @@ 340, 12 27 発言を再取得してFav結果を検証します。通信量が増えるのでOff推奨 - Reply - Favorite - プロフィール表示 - ユーザーのタイムラインを表示 - 関連発言表示 - ユーザーのHomeを開く - ステータスをWebで開く - なし + なし + Reply + Favorite + プロフィール表示 + ユーザーのタイムラインを表示 + 関連発言表示 + ユーザーのHomeを開く + ステータスをWebで開く 263, 209 232, 20 31 diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index 0268e3520..e9bd680c0 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -219,7 +219,17 @@ private string Decrypt(string password) public int ListCountApi = 100; public int UseImageService = 0; public string UseImageServiceName = ""; - public int ListDoubleClickAction = 0; + + [XmlIgnore] + public MyCommon.ListItemDoubleClickActionType ListDoubleClickAction { get; set; } = MyCommon.ListItemDoubleClickActionType.Reply; + + [XmlElement(ElementName = nameof(ListDoubleClickAction))] + public int ListDoubleClickActionNumeric + { + get => (int)this.ListDoubleClickAction; + set => this.ListDoubleClickAction = (MyCommon.ListItemDoubleClickActionType)value; + } + public string UserAppointUrl = ""; public bool HideDuplicatedRetweets = false; public bool EnableImgAzyobuziNet = true; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 52ef31222..d581edeb0 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2887,30 +2887,31 @@ private async Task ListItemDoubleClickAction() { switch (SettingManager.Common.ListDoubleClickAction) { - case 0: + case MyCommon.ListItemDoubleClickActionType.Reply: this.MakeReplyText(); break; - case 1: + case MyCommon.ListItemDoubleClickActionType.Favorite: await this.FavoriteChange(true); break; - case 2: + case MyCommon.ListItemDoubleClickActionType.ShowProfile: var post = this.CurrentPost; if (post != null) await this.ShowUserStatus(post.ScreenName, false); break; - case 3: + case MyCommon.ListItemDoubleClickActionType.ShowTimeline: await this.ShowUserTimeline(); break; - case 4: + case MyCommon.ListItemDoubleClickActionType.ShowRelated: this.ShowRelatedStatusesMenuItem_Click(this.ShowRelatedStatusesMenuItem, EventArgs.Empty); break; - case 5: + case MyCommon.ListItemDoubleClickActionType.OpenHomeInBrowser: this.AuthorOpenInBrowserMenuItem_Click(this.AuthorOpenInBrowserContextMenuItem, EventArgs.Empty); break; - case 6: + case MyCommon.ListItemDoubleClickActionType.OpenStatusInBrowser: this.StatusOpenMenuItem_Click(this.StatusOpenMenuItem, EventArgs.Empty); break; - case 7: + case MyCommon.ListItemDoubleClickActionType.None: + default: // 動作なし break; } From ad4411700f1084b0d097a1771801c7c585944260 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 07:49:13 +0900 Subject: [PATCH 128/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E3=81=AE=E3=83=80?= =?UTF-8?q?=E3=83=96=E3=83=AB=E3=82=AF=E3=83=AA=E3=83=83=E3=82=AF=E6=99=82?= =?UTF-8?q?=E3=81=AE=E5=8B=95=E4=BD=9C=E3=81=AB=20Reply=20All=20=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/MyCommon.cs | 1 + OpenTween/Resources/ChangeLog.txt | 1 + .../Setting/Panel/ActionPanel.Designer.cs | 3 ++- OpenTween/Setting/Panel/ActionPanel.cs | 26 ++++++++++--------- OpenTween/Setting/Panel/ActionPanel.en.resx | 10 +++---- OpenTween/Setting/Panel/ActionPanel.resx | 13 +++++----- OpenTween/Tween.cs | 3 +++ 7 files changed, 33 insertions(+), 24 deletions(-) diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 1b998fb4e..6b9393e4d 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -132,6 +132,7 @@ public enum ListItemDoubleClickActionType OpenHomeInBrowser, OpenStatusInBrowser, None, + ReplyAll, } public enum HITRESULT diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 4bbbeaad4..2d8ab63fa 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -7,6 +7,7 @@ * NEW: 画面上に表示する解像度に応じたプロフィール画像の取得に対応 - 高DPI環境で表示した場合により高解像度のプロフィール画像が取得されるようになります - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります + * NEW: 発言のダブルクリック時の動作に「Reply All」(@返信ALL)を追加 * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * CHG: DMが選択されている時は「@返信」「@返信ALL」のどちらも「DM送信」と同じ動作となるように変更 * CHG: 複数のユーザー宛のリプライ時にツイートの先頭にピリオドを加える仕様を廃止 diff --git a/OpenTween/Setting/Panel/ActionPanel.Designer.cs b/OpenTween/Setting/Panel/ActionPanel.Designer.cs index 84606f20b..5984e8de2 100644 --- a/OpenTween/Setting/Panel/ActionPanel.Designer.cs +++ b/OpenTween/Setting/Panel/ActionPanel.Designer.cs @@ -77,7 +77,8 @@ private void InitializeComponent() resources.GetString("ListDoubleClickActionComboBox.Items4"), resources.GetString("ListDoubleClickActionComboBox.Items5"), resources.GetString("ListDoubleClickActionComboBox.Items6"), - resources.GetString("ListDoubleClickActionComboBox.Items7")}); + resources.GetString("ListDoubleClickActionComboBox.Items7"), + resources.GetString("ListDoubleClickActionComboBox.Items8")}); resources.ApplyResources(this.ListDoubleClickActionComboBox, "ListDoubleClickActionComboBox"); this.ListDoubleClickActionComboBox.Name = "ListDoubleClickActionComboBox"; // diff --git a/OpenTween/Setting/Panel/ActionPanel.cs b/OpenTween/Setting/Panel/ActionPanel.cs index e5d560688..40935ab57 100644 --- a/OpenTween/Setting/Panel/ActionPanel.cs +++ b/OpenTween/Setting/Panel/ActionPanel.cs @@ -72,12 +72,13 @@ public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal) { MyCommon.ListItemDoubleClickActionType.None => 0, MyCommon.ListItemDoubleClickActionType.Reply => 1, - MyCommon.ListItemDoubleClickActionType.Favorite => 2, - MyCommon.ListItemDoubleClickActionType.ShowProfile => 3, - MyCommon.ListItemDoubleClickActionType.ShowTimeline => 4, - MyCommon.ListItemDoubleClickActionType.ShowRelated => 5, - MyCommon.ListItemDoubleClickActionType.OpenHomeInBrowser => 6, - MyCommon.ListItemDoubleClickActionType.OpenStatusInBrowser => 7, + MyCommon.ListItemDoubleClickActionType.ReplyAll => 2, + MyCommon.ListItemDoubleClickActionType.Favorite => 3, + MyCommon.ListItemDoubleClickActionType.ShowProfile => 4, + MyCommon.ListItemDoubleClickActionType.ShowTimeline => 5, + MyCommon.ListItemDoubleClickActionType.ShowRelated => 6, + MyCommon.ListItemDoubleClickActionType.OpenHomeInBrowser => 7, + MyCommon.ListItemDoubleClickActionType.OpenStatusInBrowser => 8, _ => 1, }; this.TabMouseLockCheck.Checked = settingCommon.TabMouseLock; @@ -111,12 +112,13 @@ public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal) { 0 => MyCommon.ListItemDoubleClickActionType.None, 1 => MyCommon.ListItemDoubleClickActionType.Reply, - 2 => MyCommon.ListItemDoubleClickActionType.Favorite, - 3 => MyCommon.ListItemDoubleClickActionType.ShowProfile, - 4 => MyCommon.ListItemDoubleClickActionType.ShowTimeline, - 5 => MyCommon.ListItemDoubleClickActionType.ShowRelated, - 6 => MyCommon.ListItemDoubleClickActionType.OpenHomeInBrowser, - 7 => MyCommon.ListItemDoubleClickActionType.OpenStatusInBrowser, + 2 => MyCommon.ListItemDoubleClickActionType.ReplyAll, + 3 => MyCommon.ListItemDoubleClickActionType.Favorite, + 4 => MyCommon.ListItemDoubleClickActionType.ShowProfile, + 5 => MyCommon.ListItemDoubleClickActionType.ShowTimeline, + 6 => MyCommon.ListItemDoubleClickActionType.ShowRelated, + 7 => MyCommon.ListItemDoubleClickActionType.OpenHomeInBrowser, + 8 => MyCommon.ListItemDoubleClickActionType.OpenStatusInBrowser, _ => MyCommon.ListItemDoubleClickActionType.Reply, }; settingCommon.TabMouseLock = this.TabMouseLockCheck.Checked; diff --git a/OpenTween/Setting/Panel/ActionPanel.en.resx b/OpenTween/Setting/Panel/ActionPanel.en.resx index e885b4fed..e1a4a6060 100644 --- a/OpenTween/Setting/Panel/ActionPanel.en.resx +++ b/OpenTween/Setting/Panel/ActionPanel.en.resx @@ -30,11 +30,11 @@ 484, 12 Refetch tweets and verify whether marked favorites. This option causes traffic increasement. Do nothing - Show user's profile - Show user's timeline - Show Relational tweet - Open user's home of twitter.com - Open status of twitter.com + Show user's profile + Show user's timeline + Show Relational tweet + Open user's home of twitter.com + Open status of twitter.com 215, 16 Play sounds when new status arrived 157, 16 diff --git a/OpenTween/Setting/Panel/ActionPanel.resx b/OpenTween/Setting/Panel/ActionPanel.resx index f9bf5b618..3a0b1857a 100644 --- a/OpenTween/Setting/Panel/ActionPanel.resx +++ b/OpenTween/Setting/Panel/ActionPanel.resx @@ -209,12 +209,13 @@ 発言を再取得してFav結果を検証します。通信量が増えるのでOff推奨 なし Reply - Favorite - プロフィール表示 - ユーザーのタイムラインを表示 - 関連発言表示 - ユーザーのHomeを開く - ステータスをWebで開く + Reply All + Favorite + プロフィール表示 + ユーザーのタイムラインを表示 + 関連発言表示 + ユーザーのHomeを開く + ステータスをWebで開く 263, 209 232, 20 31 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index d581edeb0..97a7b1b1b 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2890,6 +2890,9 @@ private async Task ListItemDoubleClickAction() case MyCommon.ListItemDoubleClickActionType.Reply: this.MakeReplyText(); break; + case MyCommon.ListItemDoubleClickActionType.ReplyAll: + this.MakeReplyText(atAll: true); + break; case MyCommon.ListItemDoubleClickActionType.Favorite: await this.FavoriteChange(true); break; From b49a4041a1b3ce05d823f8e9b8568d744d440542 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 08:48:53 +0900 Subject: [PATCH 129/402] =?UTF-8?q?=E9=96=A2=E9=80=A3=E7=99=BA=E8=A8=80?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E3=81=AB=E3=82=88=E3=81=A3=E3=81=A6=E5=86=85?= =?UTF-8?q?=E9=83=A8=E3=81=AE=E6=9C=AA=E8=AA=AD=E7=8A=B6=E6=85=8B=E3=81=A8?= =?UTF-8?q?=E6=9C=AA=E8=AA=AD=E8=A1=A8=E7=A4=BA=E3=81=8C=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E3=81=97=E3=81=AA=E3=81=84=E7=8A=B6=E6=85=8B=E3=81=AB=E3=81=AA?= =?UTF-8?q?=E3=82=8B=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=20(thx=20@wal=5Fsan!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://twitter.com/wal_san/status/1489886234990178304 Fixes: a53f5b1a ("PostClass.Cloneメソッドを廃止") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Twitter.cs | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 2d8ab63fa..1fe0ad63e 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -17,6 +17,7 @@ * FIX: 等幅フォント表示を有効にした場合に背景色の設定が全面に適用されない不具合を修正 (thx @StoutAmmo!) * FIX: 起動直後の時点で発言詳細欄の背景色設定が適用されていない不具合を修正 * FIX: 自分のツイートに対する「@返信ALL」で自分宛のMentionが付かない不具合を修正 (thx @doug_lee42!) + * FIX: 関連発言表示によって内部の未読状態と未読表示が一致しない状態になる不具合を修正 (thx @wal_san!) ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 2ee470005..56acd5348 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1069,12 +1069,13 @@ public async Task GetRelatedResult(bool read, RelatedPostsTabModel tab) relPosts.Values.ToList().ForEach(p => { - if (p.IsMe && !read && this.ReadOwnPost) - p.IsRead = true; + var post = p.Clone(); + if (post.IsMe && !read && this.ReadOwnPost) + post.IsRead = true; else - p.IsRead = read; + post.IsRead = read; - tab.AddPostQueue(p); + tab.AddPostQueue(post); }); if (lastException != null) From 3e37c7a7d09a9f04ebc0d3c41276e26dbb432b4b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 17:22:02 +0900 Subject: [PATCH 130/402] =?UTF-8?q?C#=20=E3=81=AE=E8=A8=80=E8=AA=9E?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=92=20C#=201?= =?UTF-8?q?0.0=20=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/OpenTween.Tests.csproj | 2 +- OpenTween.sln | 6 +++--- OpenTween/OpenTween.csproj | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index 36821621d..1bfb67c83 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -3,7 +3,7 @@ OpenTween net472 - 8.0 + 10.0 enable true diff --git a/OpenTween.sln b/OpenTween.sln index f85960885..126220171 100644 --- a/OpenTween.sln +++ b/OpenTween.sln @@ -1,8 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29215.179 -MinimumVisualStudioVersion = 16.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32319.34 +MinimumVisualStudioVersion = 17.0 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTween", "OpenTween\OpenTween.csproj", "{3D8995C7-BDF3-4273-9F9D-DDD902F6A101}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTween.Tests", "OpenTween.Tests\OpenTween.Tests.csproj", "{18A32642-A8F3-425B-978D-0C6F630EDDE8}" diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 16fd1c0d9..d5115412a 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -9,7 +9,7 @@ OpenTween OpenTween v4.7.2 - 8.0 + 10.0 512 true $(MSBuildProjectDirectory)=. From affffc2fe051802fcfb1f7dc36ead937665762a9 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:30:45 +0900 Subject: [PATCH 131/402] =?UTF-8?q?=E5=80=A4=E3=81=AE=E3=82=B9=E3=83=AF?= =?UTF-8?q?=E3=83=83=E3=83=97=E3=81=AB=E3=82=BF=E3=83=97=E3=83=AB=E3=82=92?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B=20(IDE0180)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/OTSplitContainer.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/OpenTween/OTSplitContainer.cs b/OpenTween/OTSplitContainer.cs index de63fcc62..60b514cf6 100644 --- a/OpenTween/OTSplitContainer.cs +++ b/OpenTween/OTSplitContainer.cs @@ -62,13 +62,8 @@ public bool IsPanelInverted base.SplitterDistance = this.SplitterTotalWidth - (base.SplitterDistance + this.SplitterWidth); - var tmpMinSize = base.Panel1MinSize; - base.Panel1MinSize = base.Panel2MinSize; - base.Panel2MinSize = tmpMinSize; - - var tmpCollapsed = base.Panel1Collapsed; - base.Panel1Collapsed = base.Panel2Collapsed; - base.Panel2Collapsed = tmpCollapsed; + (base.Panel2MinSize, base.Panel1MinSize) = (base.Panel1MinSize, base.Panel2MinSize); + (base.Panel2Collapsed, base.Panel1Collapsed) = (base.Panel1Collapsed, base.Panel2Collapsed); base.Panel1.Controls.AddRange(cont2.ToArray()); base.Panel2.Controls.AddRange(cont1.ToArray()); From 0485746be5959884b0f980974edc9d3a14c61b2e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 17:22:33 +0900 Subject: [PATCH 132/402] =?UTF-8?q?=E7=B0=A1=E7=95=A5=E5=8C=96=E3=81=97?= =?UTF-8?q?=E3=81=9F=20new=20=E5=BC=8F=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99?= =?UTF-8?q?=E3=82=8B=20(IDE0090)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/AnyOrderComparer.cs | 2 +- OpenTween.Tests/Api/ApiLimitTest.cs | 2 +- OpenTween.Tests/Api/TwitterApiStatusTest.cs | 6 ++-- OpenTween.Tests/DateTimeUtcTest.cs | 6 ++-- OpenTween.Tests/DebounceTimerTest.cs | 2 +- OpenTween.Tests/HttpMessageHandlerMock.cs | 2 +- OpenTween.Tests/Models/PostClassTest.cs | 2 +- OpenTween.Tests/MyCommonTest.cs | 6 ++-- OpenTween.Tests/TestUtils.cs | 2 +- OpenTween.Tests/ThrottleTimerTest.cs | 2 +- OpenTween.Tests/TimelineScheduerTest.cs | 2 +- OpenTween/Api/BitlyApi.cs | 2 +- .../Api/DataModel/TwitterStreamMessage.cs | 2 +- OpenTween/Api/ImgurApi.cs | 2 +- OpenTween/Api/MicrosoftTranslatorApi.cs | 4 +-- OpenTween/Api/MobypictureApi.cs | 6 ++-- OpenTween/Api/TwitterApiException.cs | 6 ++-- OpenTween/Api/TwitterApiStatus.cs | 2 +- OpenTween/ApiInfoDialog.cs | 2 +- OpenTween/ApiKey.cs | 2 +- OpenTween/AppendSettingDialog.cs | 2 +- OpenTween/Bing.cs | 2 +- OpenTween/Connection/LazyJson.cs | 2 +- OpenTween/Connection/OAuthUtility.cs | 2 +- OpenTween/Connection/TwitterApiConnection.cs | 2 +- OpenTween/DateTimeUtc.cs | 8 ++--- OpenTween/DebounceTimer.cs | 4 +-- OpenTween/Extensions.cs | 8 ++--- OpenTween/FilterDialog.cs | 4 +-- OpenTween/ImageCache.cs | 2 +- OpenTween/ImageListViewItem.cs | 2 +- OpenTween/InternetSecurityManager.cs | 10 +++--- OpenTween/ListElement.cs | 2 +- OpenTween/MediaSelector.cs | 2 +- OpenTween/Models/FilterTabModel.cs | 4 +-- OpenTween/Models/HomeTabModel.cs | 2 +- OpenTween/Models/InternalStorageTabModel.cs | 2 +- OpenTween/Models/PostClass.cs | 2 +- OpenTween/Models/TabInformations.cs | 22 ++++++------ OpenTween/Models/TabModel.cs | 12 +++---- OpenTween/MouseWheelMessageFilter.cs | 2 +- OpenTween/MyCommon.cs | 6 ++-- OpenTween/ReaderWriterLockTransaction.cs | 2 +- OpenTween/Setting/SettingBase.cs | 2 +- OpenTween/Setting/SettingCommon.cs | 6 ++-- OpenTween/Setting/SettingLocal.cs | 12 +++---- OpenTween/Setting/SettingManager.cs | 8 ++--- OpenTween/ShortUrl.cs | 8 ++--- OpenTween/ThrottleTimer.cs | 4 +-- OpenTween/Thumbnail/MapThumbOSM.cs | 2 +- .../Thumbnail/Services/FoursquareCheckin.cs | 4 +-- .../Thumbnail/Services/ImgAzyobuziNet.cs | 2 +- OpenTween/Thumbnail/Services/Nicovideo.cs | 2 +- OpenTween/Thumbnail/Services/PbsTwimgCom.cs | 4 +-- OpenTween/Thumbnail/Services/Tinami.cs | 2 +- OpenTween/Thumbnail/Services/Tumblr.cs | 2 +- OpenTween/Thumbnail/Services/Vimeo.cs | 2 +- OpenTween/Thumbnail/Services/Youtube.cs | 2 +- OpenTween/Thumbnail/ThumbnailGenerator.cs | 2 +- OpenTween/Tween.cs | 34 +++++++++---------- OpenTween/TweetExtractor.cs | 2 +- OpenTween/TweetThumbnail.cs | 4 +-- OpenTween/Twitter.cs | 14 ++++---- 63 files changed, 143 insertions(+), 143 deletions(-) diff --git a/OpenTween.Tests/AnyOrderComparer.cs b/OpenTween.Tests/AnyOrderComparer.cs index 1aa5f8b50..c4cb10edf 100644 --- a/OpenTween.Tests/AnyOrderComparer.cs +++ b/OpenTween.Tests/AnyOrderComparer.cs @@ -32,7 +32,7 @@ namespace OpenTween internal class AnyOrderComparer : IEqualityComparer> where T : IEquatable { - public static readonly AnyOrderComparer Instance = new AnyOrderComparer(); + public static readonly AnyOrderComparer Instance = new(); public bool Equals(IEnumerable x, IEnumerable y) { diff --git a/OpenTween.Tests/Api/ApiLimitTest.cs b/OpenTween.Tests/Api/ApiLimitTest.cs index 0c0b1d534..26afe5909 100644 --- a/OpenTween.Tests/Api/ApiLimitTest.cs +++ b/OpenTween.Tests/Api/ApiLimitTest.cs @@ -30,7 +30,7 @@ namespace OpenTween.Api { public class ApiLimitTest { - public static readonly TheoryData EqualsTestCase = new TheoryData + public static readonly TheoryData EqualsTestCase = new() { { new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)), true }, { new ApiLimit(350, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)), false }, diff --git a/OpenTween.Tests/Api/TwitterApiStatusTest.cs b/OpenTween.Tests/Api/TwitterApiStatusTest.cs index 677238475..187c01568 100644 --- a/OpenTween.Tests/Api/TwitterApiStatusTest.cs +++ b/OpenTween.Tests/Api/TwitterApiStatusTest.cs @@ -49,7 +49,7 @@ public void ResetTest() Assert.Equal(TwitterApiAccessLevel.Anonymous, apiStatus.AccessLevel); } - public static readonly TheoryData, ApiLimit?> ParseRateLimitTestCase = new TheoryData, ApiLimit?> + public static readonly TheoryData, ApiLimit?> ParseRateLimitTestCase = new() { { new Dictionary @@ -96,7 +96,7 @@ public void ParseRateLimitTest(IDictionary header, ApiLimit? exp Assert.Equal(expected, limit); } - public static readonly TheoryData, ApiLimit?> ParseMediaRateLimitTestCase = new TheoryData, ApiLimit?> + public static readonly TheoryData, ApiLimit?> ParseMediaRateLimitTestCase = new() { { new Dictionary @@ -134,7 +134,7 @@ public void ParseMediaRateLimitTest(IDictionary header, ApiLimit Assert.Equal(expected, limit); } - public static readonly TheoryData, TwitterApiAccessLevel?> ParseAccessLevelTestCase = new TheoryData, TwitterApiAccessLevel?> + public static readonly TheoryData, TwitterApiAccessLevel?> ParseAccessLevelTestCase = new() { { new Dictionary { { "X-Access-Level", "read" } }, diff --git a/OpenTween.Tests/DateTimeUtcTest.cs b/OpenTween.Tests/DateTimeUtcTest.cs index 532deec73..8f9d9f167 100644 --- a/OpenTween.Tests/DateTimeUtcTest.cs +++ b/OpenTween.Tests/DateTimeUtcTest.cs @@ -269,7 +269,7 @@ public void FromUnixTime_Test() utc.ToDateTimeUnsafe()); } - public static readonly TheoryData ParseTestFixtures = new TheoryData + public static readonly TheoryData ParseTestFixtures = new() { { "2018-05-06T11:22:33.111", new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, { "2018-05-06T11:22:33.111+00:00", new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, @@ -285,7 +285,7 @@ public void Parse_Test(string input, DateTimeUtc expected) public void Parse_ErrorTest() => Assert.Throws(() => DateTimeUtc.Parse("### INVALID ###", DateTimeFormatInfo.InvariantInfo)); - public static readonly TheoryData TryParseTestFixtures = new TheoryData + public static readonly TheoryData TryParseTestFixtures = new() { { "2018-05-06T11:22:33.111", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, { "2018-05-06T11:22:33.111+00:00", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, @@ -303,7 +303,7 @@ public void TryParse_Test(string input, bool expectedParsed, DateTimeUtc expecte Assert.Equal(expectedResult, result); } - public static readonly TheoryData TryParseExactTestFixtures = new TheoryData + public static readonly TheoryData TryParseExactTestFixtures = new() { { "2018-05-06 11:22:33.111", "yyyy-MM-dd HH:mm:ss.fff", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, { "2018-05-06 11:22:33.111 +00:00", "yyyy-MM-dd HH:mm:ss.fff zzz", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) }, diff --git a/OpenTween.Tests/DebounceTimerTest.cs b/OpenTween.Tests/DebounceTimerTest.cs index 188e1b0bf..a9fdd50de 100644 --- a/OpenTween.Tests/DebounceTimerTest.cs +++ b/OpenTween.Tests/DebounceTimerTest.cs @@ -32,7 +32,7 @@ public class DebounceTimerTest { private class TestDebounceTimer : DebounceTimer { - public MockTimer MockTimer = new MockTimer(() => Task.CompletedTask); + public MockTimer MockTimer = new(() => Task.CompletedTask); public TestDebounceTimer(Func timerCallback, TimeSpan interval, bool leading, bool trailing) : base(timerCallback, interval, leading, trailing) diff --git a/OpenTween.Tests/HttpMessageHandlerMock.cs b/OpenTween.Tests/HttpMessageHandlerMock.cs index bfa72e974..60994232d 100644 --- a/OpenTween.Tests/HttpMessageHandlerMock.cs +++ b/OpenTween.Tests/HttpMessageHandlerMock.cs @@ -32,7 +32,7 @@ namespace OpenTween public class HttpMessageHandlerMock : HttpMessageHandler { private readonly Queue>> queue = - new Queue>>(); + new(); public int QueueCount => this.queue.Count; diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index c385806f8..26da96d27 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -403,7 +403,7 @@ public void ConvertToOriginalPost_ErrorTest() private class FakeExpandedUrlInfo : PostClass.ExpandedUrlInfo { - public TaskCompletionSource FakeResult = new TaskCompletionSource(); + public TaskCompletionSource FakeResult = new(); public FakeExpandedUrlInfo(string url, string expandedUrl, bool deepExpand) : base(url, expandedUrl, deepExpand) diff --git a/OpenTween.Tests/MyCommonTest.cs b/OpenTween.Tests/MyCommonTest.cs index 6c50d95c9..0efa75fc2 100644 --- a/OpenTween.Tests/MyCommonTest.cs +++ b/OpenTween.Tests/MyCommonTest.cs @@ -104,7 +104,7 @@ public void ResizeBytesArrayTest(byte[] bytes, int size, byte[] expected) public void IsAnimatedGifTest(string filename, bool expected) => Assert.Equal(expected, MyCommon.IsAnimatedGif(filename)); - public static readonly TheoryData DateTimeParseTestCase = new TheoryData + public static readonly TheoryData DateTimeParseTestCase = new() { { "Sun Nov 25 06:10:00 +00:00 2012", new DateTimeUtc(2012, 11, 25, 6, 10, 0) }, { "Sun, 25 Nov 2012 06:10:00 +00:00", new DateTimeUtc(2012, 11, 25, 6, 10, 0) }, @@ -125,7 +125,7 @@ public struct JsonData public string Body { get; set; } } - public static readonly TheoryData CreateDataFromJsonTestCase = new TheoryData + public static readonly TheoryData CreateDataFromJsonTestCase = new() { { @"{""id"":""1"", ""body"":""hogehoge""}", @@ -186,7 +186,7 @@ public void ReplaceAppNameTest(string str, string excepted) public void GetReadableVersionTest(string fileVersion, string expected) => Assert.Equal(expected, MyCommon.GetReadableVersion(fileVersion)); - public static readonly TheoryData GetStatusUrlTest1TestCase = new TheoryData + public static readonly TheoryData GetStatusUrlTest1TestCase = new() { { new PostClass { StatusId = 249493863826350080L, ScreenName = "Favstar_LM", RetweetedId = null, RetweetedBy = null }, diff --git a/OpenTween.Tests/TestUtils.cs b/OpenTween.Tests/TestUtils.cs index cbb9e363e..60eb7cfb5 100644 --- a/OpenTween.Tests/TestUtils.cs +++ b/OpenTween.Tests/TestUtils.cs @@ -108,7 +108,7 @@ public static MemoryImage CreateDummyImage() } public static MemoryImageMediaItem CreateDummyMediaItem() - => new MemoryImageMediaItem(CreateDummyImage()); + => new(CreateDummyImage()); public static void FireEvent(T control, string eventName) where T : Control diff --git a/OpenTween.Tests/ThrottleTimerTest.cs b/OpenTween.Tests/ThrottleTimerTest.cs index 695416be0..0158141ed 100644 --- a/OpenTween.Tests/ThrottleTimerTest.cs +++ b/OpenTween.Tests/ThrottleTimerTest.cs @@ -33,7 +33,7 @@ public class ThrottleTimerTest { private class TestThrottleTimer : ThrottleTimer { - public MockTimer MockTimer = new MockTimer(() => Task.CompletedTask); + public MockTimer MockTimer = new(() => Task.CompletedTask); public TestThrottleTimer(Func timerCallback, TimeSpan interval) : base(timerCallback, interval) diff --git a/OpenTween.Tests/TimelineScheduerTest.cs b/OpenTween.Tests/TimelineScheduerTest.cs index e6bba7fde..6a72acbf2 100644 --- a/OpenTween.Tests/TimelineScheduerTest.cs +++ b/OpenTween.Tests/TimelineScheduerTest.cs @@ -32,7 +32,7 @@ public class TimelineScheduerTest { private class TestTimelineScheduler : TimelineScheduler { - public MockTimer MockTimer = new MockTimer(() => Task.CompletedTask); + public MockTimer MockTimer = new(() => Task.CompletedTask); public TestTimelineScheduler() : base() diff --git a/OpenTween/Api/BitlyApi.cs b/OpenTween/Api/BitlyApi.cs index ca5897662..922b1a13b 100644 --- a/OpenTween/Api/BitlyApi.cs +++ b/OpenTween/Api/BitlyApi.cs @@ -38,7 +38,7 @@ namespace OpenTween.Api { public class BitlyApi { - public static readonly Uri ApiBase = new Uri("https://api-ssl.bitly.com/"); + public static readonly Uri ApiBase = new("https://api-ssl.bitly.com/"); public string EndUserAccessToken { get; set; } = ""; diff --git a/OpenTween/Api/DataModel/TwitterStreamMessage.cs b/OpenTween/Api/DataModel/TwitterStreamMessage.cs index 32263f623..4a7d2a615 100644 --- a/OpenTween/Api/DataModel/TwitterStreamMessage.cs +++ b/OpenTween/Api/DataModel/TwitterStreamMessage.cs @@ -38,7 +38,7 @@ public StreamMessageStatus(TwitterStatusCompat status) => this.Status = status; public static StreamMessageStatus ParseJson(string json) - => new StreamMessageStatus(TwitterStatusCompat.ParseJson(json)); + => new(TwitterStatusCompat.ParseJson(json)); } public class StreamMessageKeepAlive : ITwitterStreamMessage diff --git a/OpenTween/Api/ImgurApi.cs b/OpenTween/Api/ImgurApi.cs index 0b9003ed3..591bec315 100644 --- a/OpenTween/Api/ImgurApi.cs +++ b/OpenTween/Api/ImgurApi.cs @@ -40,7 +40,7 @@ public class ImgurApi : IImgurApi private readonly ApiKey clientId; private readonly HttpClient http; - public static readonly Uri UploadEndpoint = new Uri("https://api.imgur.com/3/image.xml"); + public static readonly Uri UploadEndpoint = new("https://api.imgur.com/3/image.xml"); public ImgurApi() : this(ApplicationSettings.ImgurClientId, null) diff --git a/OpenTween/Api/MicrosoftTranslatorApi.cs b/OpenTween/Api/MicrosoftTranslatorApi.cs index e194d655c..363946841 100644 --- a/OpenTween/Api/MicrosoftTranslatorApi.cs +++ b/OpenTween/Api/MicrosoftTranslatorApi.cs @@ -38,8 +38,8 @@ namespace OpenTween.Api { public class MicrosoftTranslatorApi { - public static readonly Uri IssueTokenEndpoint = new Uri("https://api.cognitive.microsoft.com/sts/v1.0/issueToken"); - public static readonly Uri TranslateEndpoint = new Uri("https://api.cognitive.microsofttranslator.com/translate"); + public static readonly Uri IssueTokenEndpoint = new("https://api.cognitive.microsoft.com/sts/v1.0/issueToken"); + public static readonly Uri TranslateEndpoint = new("https://api.cognitive.microsofttranslator.com/translate"); public string AccessToken { get; internal set; } = ""; diff --git a/OpenTween/Api/MobypictureApi.cs b/OpenTween/Api/MobypictureApi.cs index 255267e6e..d76d4347c 100644 --- a/OpenTween/Api/MobypictureApi.cs +++ b/OpenTween/Api/MobypictureApi.cs @@ -39,10 +39,10 @@ public class MobypictureApi : IMobypictureApi private readonly ApiKey apiKey; private readonly HttpClient http; - public static readonly Uri UploadEndpoint = new Uri("https://api.mobypicture.com/2.0/upload.xml"); + public static readonly Uri UploadEndpoint = new("https://api.mobypicture.com/2.0/upload.xml"); - private static readonly Uri OAuthRealm = new Uri("http://api.twitter.com/"); - private static readonly Uri AuthServiceProvider = new Uri("https://api.twitter.com/1.1/account/verify_credentials.json"); + private static readonly Uri OAuthRealm = new("http://api.twitter.com/"); + private static readonly Uri AuthServiceProvider = new("https://api.twitter.com/1.1/account/verify_credentials.json"); public MobypictureApi(TwitterApi twitterApi) : this(ApplicationSettings.MobypictureKey, twitterApi) diff --git a/OpenTween/Api/TwitterApiException.cs b/OpenTween/Api/TwitterApiException.cs index 28418166f..e2b9de049 100644 --- a/OpenTween/Api/TwitterApiException.cs +++ b/OpenTween/Api/TwitterApiException.cs @@ -91,13 +91,13 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont } public static TwitterApiException CreateFromException(HttpRequestException ex) - => new TwitterApiException(ex.InnerException?.Message ?? ex.Message, ex); + => new(ex.InnerException?.Message ?? ex.Message, ex); public static TwitterApiException CreateFromException(OperationCanceledException ex) - => new TwitterApiException("Timeout", ex); + => new("Timeout", ex); public static TwitterApiException CreateFromException(SerializationException ex, string responseText) - => new TwitterApiException("Invalid JSON", responseText, ex); + => new("Invalid JSON", responseText, ex); private static string FormatTwitterError(TwitterError error) => string.Join(",", error.Errors.Select(x => x.ToString())); diff --git a/OpenTween/Api/TwitterApiStatus.cs b/OpenTween/Api/TwitterApiStatus.cs index 50a1348c9..27a318cdc 100644 --- a/OpenTween/Api/TwitterApiStatus.cs +++ b/OpenTween/Api/TwitterApiStatus.cs @@ -157,7 +157,7 @@ public class EndpointLimits : IEnumerable> public TwitterApiStatus Owner { get; } private readonly ConcurrentDictionary innerDict - = new ConcurrentDictionary(); + = new(); public EndpointLimits(TwitterApiStatus owner) => this.Owner = owner; diff --git a/OpenTween/ApiInfoDialog.cs b/OpenTween/ApiInfoDialog.cs index 05c10bd64..e8240a097 100644 --- a/OpenTween/ApiInfoDialog.cs +++ b/OpenTween/ApiInfoDialog.cs @@ -39,7 +39,7 @@ public partial class ApiInfoDialog : OTBaseForm public ApiInfoDialog() => this.InitializeComponent(); - private readonly List tlEndpoints = new List + private readonly List tlEndpoints = new() { "/statuses/home_timeline", "/statuses/mentions_timeline", diff --git a/OpenTween/ApiKey.cs b/OpenTween/ApiKey.cs index 0ed7920ec..a9c4f8759 100644 --- a/OpenTween/ApiKey.cs +++ b/OpenTween/ApiKey.cs @@ -89,7 +89,7 @@ public static ApiKey Create(string rawKey) /// インスタンスを作成します /// public static ApiKey Create(string password, string rawKey) - => new ApiKey(password, rawKey); + => new(password, rawKey); /// /// 指定された文字列を暗号化して返します diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index a510e5c80..2d48984c6 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -328,7 +328,7 @@ public class IntervalChangedEventArgs : EventArgs public bool Lists; public bool UserTimeline; - public static IntervalChangedEventArgs ResetAll => new IntervalChangedEventArgs + public static IntervalChangedEventArgs ResetAll => new() { Timeline = true, Reply = true, diff --git a/OpenTween/Bing.cs b/OpenTween/Bing.cs index a7be3b739..9ae3da1cf 100644 --- a/OpenTween/Bing.cs +++ b/OpenTween/Bing.cs @@ -39,7 +39,7 @@ namespace OpenTween { public class Bing { - private static readonly List LanguageTable = new List + private static readonly List LanguageTable = new() { "af", "sq", diff --git a/OpenTween/Connection/LazyJson.cs b/OpenTween/Connection/LazyJson.cs index 6bcca4523..2f0bc80e0 100644 --- a/OpenTween/Connection/LazyJson.cs +++ b/OpenTween/Connection/LazyJson.cs @@ -83,7 +83,7 @@ public void Dispose() public static class LazyJson { public static LazyJson Create(T instance) - => new LazyJson(instance); + => new(instance); } public static class LazyJsonTaskExtension diff --git a/OpenTween/Connection/OAuthUtility.cs b/OpenTween/Connection/OAuthUtility.cs index 0e98f7113..dba7ada7f 100644 --- a/OpenTween/Connection/OAuthUtility.cs +++ b/OpenTween/Connection/OAuthUtility.cs @@ -42,7 +42,7 @@ public static class OAuthUtility /// /// OAuth署名のoauth_nonce算出用乱数クラス /// - private static readonly Random NonceRandom = new Random(); + private static readonly Random NonceRandom = new(); /// /// HTTPリクエストに追加するAuthorizationヘッダの値を生成します diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index 23980a431..b21bd81a1 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -40,7 +40,7 @@ namespace OpenTween.Connection { public class TwitterApiConnection : IApiConnection, IDisposable { - public static Uri RestApiBase { get; set; } = new Uri("https://api.twitter.com/1.1/"); + public static Uri RestApiBase { get; set; } = new("https://api.twitter.com/1.1/"); // SettingCommon.xml の TwitterUrl との互換性のために用意 public static string RestApiHost diff --git a/OpenTween/DateTimeUtc.cs b/OpenTween/DateTimeUtc.cs index a81dd2580..b89abd391 100644 --- a/OpenTween/DateTimeUtc.cs +++ b/OpenTween/DateTimeUtc.cs @@ -90,7 +90,7 @@ public long ToUnixTime() => (long)(this - UnixEpoch).TotalSeconds; public DateTimeOffset ToDateTimeOffset() - => new DateTimeOffset(this.datetime); + => new(this.datetime); public DateTimeOffset ToLocalTime() => this.ToDateTimeOffset().ToLocalTime(); @@ -123,10 +123,10 @@ public string ToLocalTimeString(string format) => this.ToLocalTime().ToString(format); public static DateTimeUtc operator +(DateTimeUtc a, TimeSpan b) - => new DateTimeUtc(a.datetime + b); + => new(a.datetime + b); public static DateTimeUtc operator -(DateTimeUtc a, TimeSpan b) - => new DateTimeUtc(a.datetime - b); + => new(a.datetime - b); public static TimeSpan operator -(DateTimeUtc a, DateTimeUtc b) => a.datetime - b.datetime; @@ -153,7 +153,7 @@ public static DateTimeUtc FromUnixTime(long unixTime) => UnixEpoch + TimeSpan.FromTicks(unixTime * TimeSpan.TicksPerSecond); public static DateTimeUtc Parse(string input, IFormatProvider formatProvider) - => new DateTimeUtc(DateTimeOffset.Parse(input, formatProvider, DateTimeStyles.AssumeUniversal)); + => new(DateTimeOffset.Parse(input, formatProvider, DateTimeStyles.AssumeUniversal)); public static bool TryParse(string input, IFormatProvider formatProvider, out DateTimeUtc result) { diff --git a/OpenTween/DebounceTimer.cs b/OpenTween/DebounceTimer.cs index f88a040d8..cc728cbb0 100644 --- a/OpenTween/DebounceTimer.cs +++ b/OpenTween/DebounceTimer.cs @@ -37,7 +37,7 @@ public class DebounceTimer : IDisposable { private readonly ITimer debouncingTimer; private readonly Func timerCallback; - private readonly object lockObject = new object(); + private readonly object lockObject = new(); private DateTimeUtc lastCall; private bool calledSinceLastInvoke; @@ -145,6 +145,6 @@ public void Dispose() => this.debouncingTimer.Dispose(); public static DebounceTimer Create(Func callback, TimeSpan wait, bool leading = false, bool trailing = true) - => new DebounceTimer(callback, wait, leading, trailing); + => new(callback, wait, leading, trailing); } } diff --git a/OpenTween/Extensions.cs b/OpenTween/Extensions.cs index 98328ddc5..788fed1e8 100644 --- a/OpenTween/Extensions.cs +++ b/OpenTween/Extensions.cs @@ -47,13 +47,13 @@ public static string GetSelectedText(this WebBrowser webBrowser) } public static ReadLockTransaction BeginReadTransaction(this ReaderWriterLockSlim lockObj) - => new ReadLockTransaction(lockObj); + => new(lockObj); public static WriteLockTransaction BeginWriteTransaction(this ReaderWriterLockSlim lockObj) - => new WriteLockTransaction(lockObj); + => new(lockObj); public static UpgradeableReadLockTransaction BeginUpgradeableReadTransaction(this ReaderWriterLockSlim lockObj) - => new UpgradeableReadLockTransaction(lockObj); + => new(lockObj); /// /// 一方のカルチャがもう一方のカルチャを内包するかを判断します @@ -195,7 +195,7 @@ public static async Task ForEachAsync(this IObservable observable, Func : IObserver { private readonly Func subscriber; - private readonly TaskCompletionSource tcs = new TaskCompletionSource(); + private readonly TaskCompletionSource tcs = new(); public Task Task => this.tcs.Task; diff --git a/OpenTween/FilterDialog.cs b/OpenTween/FilterDialog.cs index a6df3cd6c..14ca329b9 100644 --- a/OpenTween/FilterDialog.cs +++ b/OpenTween/FilterDialog.cs @@ -49,10 +49,10 @@ public partial class FilterDialog : OTBaseForm private MultiSelectionState multiSelState = MultiSelectionState.None; private readonly TabInformations sts; - private List tabs = new List(); + private List tabs = new(); private int selectedTabIndex = -1; - private readonly List idlist = new List(); + private readonly List idlist = new(); private enum EDITMODE { diff --git a/OpenTween/ImageCache.cs b/OpenTween/ImageCache.cs index 8b98b8d25..690a7aced 100644 --- a/OpenTween/ImageCache.cs +++ b/OpenTween/ImageCache.cs @@ -49,7 +49,7 @@ public class ImageCache : IDisposable /// /// innerDictionary の排他制御のためのロックオブジェクト /// - private readonly object lockObject = new object(); + private readonly object lockObject = new(); /// /// オブジェクトが破棄された否か diff --git a/OpenTween/ImageListViewItem.cs b/OpenTween/ImageListViewItem.cs index 74d2335d2..5d3a84ffa 100644 --- a/OpenTween/ImageListViewItem.cs +++ b/OpenTween/ImageListViewItem.cs @@ -48,7 +48,7 @@ public class ImageListViewItem : ListViewItem /// public int StateIndex { get; set; } - private readonly WeakReference imageReference = new WeakReference(null); + private readonly WeakReference imageReference = new(null); private Task? imageTask = null; public event EventHandler? ImageDownloaded; diff --git a/OpenTween/InternetSecurityManager.cs b/OpenTween/InternetSecurityManager.cs index 0a3a97aec..e5f4bee61 100644 --- a/OpenTween/InternetSecurityManager.cs +++ b/OpenTween/InternetSecurityManager.cs @@ -58,9 +58,9 @@ public enum POLICY ALLOW_SCRIPT = 0x2, } - private readonly object ocx = new object(); + private readonly object ocx = new(); private readonly WebBrowserAPI.IServiceProvider ocxServiceProvider; - private readonly IntPtr profferServicePtr = new IntPtr(); + private readonly IntPtr profferServicePtr = new(); private readonly WebBrowserAPI.IProfferService profferService = null!; public POLICY SecurityPolicy { get; set; } = 0; @@ -376,9 +376,9 @@ public enum URLZONE // ---------------------------------------------------------------------- // ここ以下は COM Interface の宣言です。 - public static Guid IID_IProfferService = new Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0"); - public static Guid SID_SProfferService = new Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0"); - public static Guid IID_IInternetSecurityManager = new Guid("79eac9ee-baf9-11ce-8c82-00aa004ba90b"); + public static Guid IID_IProfferService = new("cb728b20-f786-11ce-92ad-00aa00a74cd0"); + public static Guid SID_SProfferService = new("cb728b20-f786-11ce-92ad-00aa00a74cd0"); + public static Guid IID_IInternetSecurityManager = new("79eac9ee-baf9-11ce-8c82-00aa004ba90b"); [ComImport] [Guid("6d5140c1-7436-11ce-8034-00aa006009fa")] diff --git a/OpenTween/ListElement.cs b/OpenTween/ListElement.cs index 08e239e2a..b7c9d4da8 100644 --- a/OpenTween/ListElement.cs +++ b/OpenTween/ListElement.cs @@ -48,7 +48,7 @@ public class ListElement protected Twitter tw = null!; - private List members = new List(); + private List members = new(); [XmlIgnore] public long Cursor { get; private set; } = -1; diff --git a/OpenTween/MediaSelector.cs b/OpenTween/MediaSelector.cs index 36bea22a5..bffec5451 100644 --- a/OpenTween/MediaSelector.cs +++ b/OpenTween/MediaSelector.cs @@ -134,7 +134,7 @@ public override string ToString() => this.Text; } - private Dictionary pictureService = new Dictionary(); + private Dictionary pictureService = new(); private void CreateServices(Twitter tw, TwitterConfiguration twitterConfig) { diff --git a/OpenTween/Models/FilterTabModel.cs b/OpenTween/Models/FilterTabModel.cs index ddf36badb..a6c32b8a0 100644 --- a/OpenTween/Models/FilterTabModel.cs +++ b/OpenTween/Models/FilterTabModel.cs @@ -43,8 +43,8 @@ public override MyCommon.TabUsageType TabType public bool FilterModified { get; set; } - private readonly List filters = new List(); - private readonly object lockObjFilters = new object(); + private readonly List filters = new(); + private readonly object lockObjFilters = new(); public FilterTabModel(string tabName) : base(tabName) diff --git a/OpenTween/Models/HomeTabModel.cs b/OpenTween/Models/HomeTabModel.cs index 0cb5c1f6b..41aaa1547 100644 --- a/OpenTween/Models/HomeTabModel.cs +++ b/OpenTween/Models/HomeTabModel.cs @@ -47,7 +47,7 @@ public override MyCommon.TabUsageType TabType // 流速計測用 private int tweetsPerHour = 0; - private readonly ConcurrentDictionary tweetsTimestamps = new ConcurrentDictionary(); + private readonly ConcurrentDictionary tweetsTimestamps = new(); public HomeTabModel() : this(MyCommon.DEFAULTTAB.RECENT) diff --git a/OpenTween/Models/InternalStorageTabModel.cs b/OpenTween/Models/InternalStorageTabModel.cs index 432e0a05c..81ee24140 100644 --- a/OpenTween/Models/InternalStorageTabModel.cs +++ b/OpenTween/Models/InternalStorageTabModel.cs @@ -38,7 +38,7 @@ namespace OpenTween.Models { public abstract class InternalStorageTabModel : TabModel { - protected readonly ConcurrentDictionary internalPosts = new ConcurrentDictionary(); + protected readonly ConcurrentDictionary internalPosts = new(); public override ConcurrentDictionary Posts => this.internalPosts; diff --git a/OpenTween/Models/PostClass.cs b/OpenTween/Models/PostClass.cs index e196b8495..b12ad2cdb 100644 --- a/OpenTween/Models/PostClass.cs +++ b/OpenTween/Models/PostClass.cs @@ -200,7 +200,7 @@ protected virtual async Task DeepExpandAsync() } public ExpandedUrlInfo Clone() - => new ExpandedUrlInfo(this.Url, this.ExpandedUrl, deepExpand: false); + => new(this.Url, this.ExpandedUrl, deepExpand: false); object ICloneable.Clone() => this.Clone(); diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index 480d6caf1..085047fee 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -45,14 +45,14 @@ public sealed class TabInformations public IReadOnlyTabCollection Tabs => this.tabs; - public MuteTabModel MuteTab { get; private set; } = new MuteTabModel(); + public MuteTabModel MuteTab { get; private set; } = new(); - public ConcurrentDictionary Posts { get; } = new ConcurrentDictionary(); + public ConcurrentDictionary Posts { get; } = new(); - private readonly Dictionary quotes = new Dictionary(); - private readonly ConcurrentDictionary retweetsCount = new ConcurrentDictionary(); + private readonly Dictionary quotes = new(); + private readonly ConcurrentDictionary retweetsCount = new(); - public Stack RemovedTab { get; } = new Stack(); + public Stack RemovedTab { get; } = new(); public ISet BlockIds { get; set; } = new HashSet(); @@ -61,11 +61,11 @@ public IReadOnlyTabCollection Tabs // 発言の追加 // AddPost(複数回) -> DistributePosts -> SubmitUpdate - private readonly TabCollection tabs = new TabCollection(); - private readonly ConcurrentQueue addQueue = new ConcurrentQueue(); + private readonly TabCollection tabs = new(); + private readonly ConcurrentQueue addQueue = new(); /// 通知サウンドを再生する優先順位 - private readonly Dictionary notifyPriorityByTabType = new Dictionary + private readonly Dictionary notifyPriorityByTabType = new() { [MyCommon.TabUsageType.DirectMessage] = 100, [MyCommon.TabUsageType.Mentions] = 90, @@ -75,12 +75,12 @@ public IReadOnlyTabCollection Tabs }; // トランザクション用 - private readonly object lockObj = new object(); + private readonly object lockObj = new(); - private static readonly TabInformations Instance = new TabInformations(); + private static readonly TabInformations Instance = new(); // List - private List lists = new List(); + private List lists = new(); private TabInformations() { diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index 93071f026..1b16ccde3 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -100,13 +100,13 @@ public int SelectedIndex } } - private IndexedSortedSet ids = new IndexedSortedSet(); - private ConcurrentQueue addQueue = new ConcurrentQueue(); - private readonly ConcurrentQueue removeQueue = new ConcurrentQueue(); - private SortedSet unreadIds = new SortedSet(); - private List selectedStatusIds = new List(); + private IndexedSortedSet ids = new(); + private ConcurrentQueue addQueue = new(); + private readonly ConcurrentQueue removeQueue = new(); + private SortedSet unreadIds = new(); + private List selectedStatusIds = new(); - private readonly object lockObj = new object(); + private readonly object lockObj = new(); protected TabModel(string tabName) => this.TabName = tabName; diff --git a/OpenTween/MouseWheelMessageFilter.cs b/OpenTween/MouseWheelMessageFilter.cs index 2ab198b31..3001e37f9 100644 --- a/OpenTween/MouseWheelMessageFilter.cs +++ b/OpenTween/MouseWheelMessageFilter.cs @@ -37,7 +37,7 @@ namespace OpenTween /// public class MouseWheelMessageFilter : IMessageFilter { - private readonly List controls = new List(); + private readonly List controls = new(); public MouseWheelMessageFilter() => Application.AddMessageFilter(this); diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 6b9393e4d..9407cc6a3 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -59,7 +59,7 @@ namespace OpenTween { public static class MyCommon { - private static readonly object LockObj = new object(); + private static readonly object LockObj = new(); public static bool EndingFlag { get; set; } // 終了フラグ @@ -670,7 +670,7 @@ public enum TabUsageType SearchResults = 4096, } - public static TwitterApiStatus TwitterApiInfo = new TwitterApiStatus(); + public static TwitterApiStatus TwitterApiInfo = new(); public static bool IsAnimatedGif(string filename) { @@ -874,7 +874,7 @@ public static string BuildQueryString(IEnumerable> // .NET 4.5+: Reserved characters のうち、Uriクラスによってエスケープ強制解除されてしまうものも最初から Unreserved として扱う private static readonly HashSet UnreservedChars = - new HashSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!'()*:"); + new("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!'()*:"); /// /// 2バイト文字も考慮したクエリ用エンコード diff --git a/OpenTween/ReaderWriterLockTransaction.cs b/OpenTween/ReaderWriterLockTransaction.cs index d6b1a30a2..faf42861a 100644 --- a/OpenTween/ReaderWriterLockTransaction.cs +++ b/OpenTween/ReaderWriterLockTransaction.cs @@ -70,7 +70,7 @@ public UpgradeableReadLockTransaction(ReaderWriterLockSlim lockObj) } public WriteLockTransaction UpgradeToWriteLock() - => new WriteLockTransaction(this.lockObj); + => new(this.lockObj); public void Dispose() => this.lockObj.ExitUpgradeableReadLock(); diff --git a/OpenTween/Setting/SettingBase.cs b/OpenTween/Setting/SettingBase.cs index 29bb247ef..b6c1be617 100644 --- a/OpenTween/Setting/SettingBase.cs +++ b/OpenTween/Setting/SettingBase.cs @@ -51,7 +51,7 @@ public abstract class SettingBase [XmlAnyElement] public XmlElement[] ExtraElements = Array.Empty(); - private static readonly object LockObj = new object(); + private static readonly object LockObj = new(); protected static T LoadSettings(string fileId) { diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index e9bd680c0..de6ca3ec2 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -44,7 +44,7 @@ public void Save() => SaveSettings(this); #endregion - public List UserAccounts = new List(); + public List UserAccounts = new(); public string UserName = ""; [XmlIgnore] @@ -104,7 +104,7 @@ private string Decrypt(string password) } public long UserId = 0; - public List TabList = new List(); + public List TabList = new(); public int TimelinePeriod = 90; public int ReplyPeriod = 180; public int DMPeriod = 600; @@ -166,7 +166,7 @@ private string Decrypt(string password) public bool ReadOldPosts = false; public string Language = "OS"; public bool Nicoms = false; - public List HashTags = new List(); + public List HashTags = new(); public string HashSelected = ""; public bool HashIsPermanent = false; public bool HashIsHead = false; diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index 872fbbaa3..3083a2a52 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -51,9 +51,9 @@ public void Save() /// public SizeF ScaleDimension = SizeF.Empty; - public Point FormLocation = new Point(0, 0); + public Point FormLocation = new(0, 0); public int SplitterDistance = 200; - public Size FormSize = new Size(600, 500); + public Size FormSize = new(600, 500); /// /// 文末ステータス @@ -87,7 +87,7 @@ public void Save() public int PreviewDistance = -1; [XmlIgnore] - public Font FontUnread = new Font(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline); + public Font FontUnread = new(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline); public string FontUnreadStr { @@ -341,7 +341,7 @@ public string EncryptProxyPassword public bool UseTwemoji = true; [XmlIgnore] - private readonly FontConverter fontConverter = new FontConverter(); + private readonly FontConverter fontConverter = new(); protected string FontToString(Font font) => this.fontConverter.ConvertToString(font); @@ -350,7 +350,7 @@ protected Font StringToFont(string str) => (Font)this.fontConverter.ConvertFromString(str); [XmlIgnore] - private readonly ColorConverter colorConverter = new ColorConverter(); + private readonly ColorConverter colorConverter = new(); protected string ColorToString(Color color) => this.colorConverter.ConvertToString(color); @@ -362,7 +362,7 @@ protected Color StringToColor(string str) /// 指定されたスケールと SettingLocal.ScaleDimension のスケールとの拡大比を返します /// public SizeF GetConfigScaleFactor(SizeF currentSizeDimension) - => new SizeF( + => new( currentSizeDimension.Width / this.ScaleDimension.Width, currentSizeDimension.Height / this.ScaleDimension.Height); diff --git a/OpenTween/Setting/SettingManager.cs b/OpenTween/Setting/SettingManager.cs index 12ee07dd0..9dd114146 100644 --- a/OpenTween/Setting/SettingManager.cs +++ b/OpenTween/Setting/SettingManager.cs @@ -31,13 +31,13 @@ namespace OpenTween.Setting { public static class SettingManager { - public static SettingCommon Common { get; internal set; } = new SettingCommon(); + public static SettingCommon Common { get; internal set; } = new(); - public static SettingLocal Local { get; internal set; } = new SettingLocal(); + public static SettingLocal Local { get; internal set; } = new(); - public static SettingTabs Tabs { get; internal set; } = new SettingTabs(); + public static SettingTabs Tabs { get; internal set; } = new(); - public static SettingAtIdList AtIdList { get; internal set; } = new SettingAtIdList(); + public static SettingAtIdList AtIdList { get; internal set; } = new(); public static void LoadAll() { diff --git a/OpenTween/ShortUrl.cs b/OpenTween/ShortUrl.cs index dcb4046aa..996d0e28e 100644 --- a/OpenTween/ShortUrl.cs +++ b/OpenTween/ShortUrl.cs @@ -72,11 +72,11 @@ public static ShortUrl Instance public string BitlyKey { get; set; } = ""; private HttpClient http; - private readonly ConcurrentDictionary urlCache = new ConcurrentDictionary(); + private readonly ConcurrentDictionary urlCache = new(); - private static readonly Regex HtmlLinkPattern = new Regex(@"( ShortUrlHosts = new HashSet + private static readonly HashSet ShortUrlHosts = new() { "4sq.com", "amzn.to", @@ -124,7 +124,7 @@ public static ShortUrl Instance /// /// HTTPS非対応の短縮URLサービス /// - private static readonly HashSet InsecureDomains = new HashSet + private static readonly HashSet InsecureDomains = new() { "budurl.com", "ff.im", diff --git a/OpenTween/ThrottleTimer.cs b/OpenTween/ThrottleTimer.cs index ed63bb227..5774e5beb 100644 --- a/OpenTween/ThrottleTimer.cs +++ b/OpenTween/ThrottleTimer.cs @@ -37,7 +37,7 @@ public class ThrottleTimer : IDisposable { private readonly ITimer throttlingTimer; private readonly Func timerCallback; - private readonly object lockObject = new object(); + private readonly object lockObject = new(); private bool calledSinceLastInvoke; private bool refreshTimerEnabled; @@ -118,6 +118,6 @@ public void Dispose() => this.throttlingTimer.Dispose(); public static ThrottleTimer Create(Func callback, TimeSpan wait) - => new ThrottleTimer(callback, wait); + => new(callback, wait); } } diff --git a/OpenTween/Thumbnail/MapThumbOSM.cs b/OpenTween/Thumbnail/MapThumbOSM.cs index e9319ddc3..a9216ef17 100644 --- a/OpenTween/Thumbnail/MapThumbOSM.cs +++ b/OpenTween/Thumbnail/MapThumbOSM.cs @@ -63,7 +63,7 @@ public class OSMThumbnailInfo : ThumbnailInfo public static readonly string TileServerBase = "https://a.tile.openstreetmap.org"; /// タイル画像一枚当たりの大きさ (ピクセル単位) - public static readonly Size TileSize = new Size(256, 256); + public static readonly Size TileSize = new(256, 256); /// 画像の中心点の緯度 public double Latitude { get; } diff --git a/OpenTween/Thumbnail/Services/FoursquareCheckin.cs b/OpenTween/Thumbnail/Services/FoursquareCheckin.cs index 4ff71bdff..a51252efb 100644 --- a/OpenTween/Thumbnail/Services/FoursquareCheckin.cs +++ b/OpenTween/Thumbnail/Services/FoursquareCheckin.cs @@ -41,10 +41,10 @@ namespace OpenTween.Thumbnail.Services public class FoursquareCheckin : IThumbnailService { public static readonly Regex UrlPatternRegex = - new Regex(@"^https?://www\.swarmapp\.com/c/(?[0-9a-zA-Z]+)"); + new(@"^https?://www\.swarmapp\.com/c/(?[0-9a-zA-Z]+)"); public static readonly Regex LegacyUrlPatternRegex = - new Regex(@"^https?://(?:foursquare\.com|www\.swarmapp\.com)/.+?/checkin/(?[0-9a-z]+)(?:\?s=(?[^&]+))?"); + new(@"^https?://(?:foursquare\.com|www\.swarmapp\.com)/.+?/checkin/(?[0-9a-z]+)(?:\?s=(?[^&]+))?"); public static readonly string ApiBase = "https://api.foursquare.com/v2"; diff --git a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs index c7a612309..3b9757be3 100644 --- a/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs +++ b/OpenTween/Thumbnail/Services/ImgAzyobuziNet.cs @@ -61,7 +61,7 @@ protected HttpClient Http private readonly HttpClient? localHttpClient; - private readonly object lockObj = new object(); + private readonly object lockObj = new(); public ImgAzyobuziNet(bool autoupdate) : this(null, autoupdate) diff --git a/OpenTween/Thumbnail/Services/Nicovideo.cs b/OpenTween/Thumbnail/Services/Nicovideo.cs index a31b2aaa7..ca6a51fdc 100644 --- a/OpenTween/Thumbnail/Services/Nicovideo.cs +++ b/OpenTween/Thumbnail/Services/Nicovideo.cs @@ -45,7 +45,7 @@ namespace OpenTween.Thumbnail.Services public class Nicovideo : IThumbnailService { public static readonly Regex UrlPatternRegex = - new Regex(@"^https?://(?:(www|ext)\.nicovideo\.jp/watch|nico\.ms)/(?(?:sm|nm)?[0-9]+)(\?.+)?$"); + new(@"^https?://(?:(www|ext)\.nicovideo\.jp/watch|nico\.ms)/(?(?:sm|nm)?[0-9]+)(\?.+)?$"); public override async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { diff --git a/OpenTween/Thumbnail/Services/PbsTwimgCom.cs b/OpenTween/Thumbnail/Services/PbsTwimgCom.cs index 8fe3f21f4..c7c025a31 100644 --- a/OpenTween/Thumbnail/Services/PbsTwimgCom.cs +++ b/OpenTween/Thumbnail/Services/PbsTwimgCom.cs @@ -35,10 +35,10 @@ namespace OpenTween.Thumbnail.Services public class PbsTwimgCom : IThumbnailService { public static readonly Regex ModernUrlPattern = - new Regex(@"^(?https?://pbs\.twimg\.com/[^:.]+)\?([^&]+?&)?format=(?[A-Za-z]+)"); + new(@"^(?https?://pbs\.twimg\.com/[^:.]+)\?([^&]+?&)?format=(?[A-Za-z]+)"); public static readonly Regex LegacyUrlPattern = - new Regex(@"^(?https?://pbs\.twimg\.com/[^.]+)\.(?[A-Za-z]+)(?:\:.+)?$"); + new(@"^(?https?://pbs\.twimg\.com/[^.]+)\.(?[A-Za-z]+)(?:\:.+)?$"); public override Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) => Task.FromResult(this.GetThumbnailInfo(url, post, token)); diff --git a/OpenTween/Thumbnail/Services/Tinami.cs b/OpenTween/Thumbnail/Services/Tinami.cs index 695fed7a1..4fbf1d447 100644 --- a/OpenTween/Thumbnail/Services/Tinami.cs +++ b/OpenTween/Thumbnail/Services/Tinami.cs @@ -40,7 +40,7 @@ namespace OpenTween.Thumbnail.Services public class Tinami : IThumbnailService { public static readonly Regex UrlPatternRegex = - new Regex(@"^https?://www\.tinami\.com/view/(?\d+)$"); + new(@"^https?://www\.tinami\.com/view/(?\d+)$"); protected HttpClient Http => this.localHttpClient ?? Networking.Http; diff --git a/OpenTween/Thumbnail/Services/Tumblr.cs b/OpenTween/Thumbnail/Services/Tumblr.cs index b29895955..4e1fb4cd1 100644 --- a/OpenTween/Thumbnail/Services/Tumblr.cs +++ b/OpenTween/Thumbnail/Services/Tumblr.cs @@ -41,7 +41,7 @@ namespace OpenTween.Thumbnail.Services public class Tumblr : IThumbnailService { public static readonly Regex UrlPatternRegex = - new Regex(@"^https?://(?[^.]+\.tumblr\.com|tumblr\.[^.]+\.[^.]+)/post/(?[0-9]+)(/.*)?"); + new(@"^https?://(?[^.]+\.tumblr\.com|tumblr\.[^.]+\.[^.]+)/post/(?[0-9]+)(/.*)?"); protected HttpClient Http => this.localHttpClient ?? Networking.Http; diff --git a/OpenTween/Thumbnail/Services/Vimeo.cs b/OpenTween/Thumbnail/Services/Vimeo.cs index 674196d94..41fc33910 100644 --- a/OpenTween/Thumbnail/Services/Vimeo.cs +++ b/OpenTween/Thumbnail/Services/Vimeo.cs @@ -42,7 +42,7 @@ namespace OpenTween.Thumbnail.Services public class Vimeo : IThumbnailService { public static readonly Regex UrlPatternRegex = - new Regex(@"https?://vimeo\.com/(?[0-9]+)"); + new(@"https?://vimeo\.com/(?[0-9]+)"); protected HttpClient Http => this.localHttpClient ?? Networking.Http; diff --git a/OpenTween/Thumbnail/Services/Youtube.cs b/OpenTween/Thumbnail/Services/Youtube.cs index 4577f97ff..414a72825 100644 --- a/OpenTween/Thumbnail/Services/Youtube.cs +++ b/OpenTween/Thumbnail/Services/Youtube.cs @@ -40,7 +40,7 @@ namespace OpenTween.Thumbnail.Services public class Youtube : IThumbnailService { public static readonly Regex UrlPatternRegex = - new Regex(@"^https?://(?:(?:(?:m|www|music|gaming)\.)?youtube\.com/(?:watch\?(?:[^#]*&)?v=|embed/|shorts/)|youtu\.be/)(?[\w\-]+)"); + new(@"^https?://(?:(?:(?:m|www|music|gaming)\.)?youtube\.com/(?:watch\?(?:[^#]*&)?v=|embed/|shorts/)|youtu\.be/)(?[\w\-]+)"); public override Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { diff --git a/OpenTween/Thumbnail/ThumbnailGenerator.cs b/OpenTween/Thumbnail/ThumbnailGenerator.cs index 9264d343a..39c6dbaac 100644 --- a/OpenTween/Thumbnail/ThumbnailGenerator.cs +++ b/OpenTween/Thumbnail/ThumbnailGenerator.cs @@ -36,7 +36,7 @@ namespace OpenTween.Thumbnail { public class ThumbnailGenerator { - public static readonly Regex InstagramPattern = new Regex( + public static readonly Regex InstagramPattern = new( @"^https?://(?:instagram.com|instagr\.am|i\.instagram\.com|www\.instagram\.com)/([^/]+/)?p/(?[^/]+)/(\?.*)?$", RegexOptions.IgnoreCase ); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 97a7b1b1b..17d94ba5a 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -103,7 +103,7 @@ public partial class TweenMain : OTBaseForm /// 右クリックしたタブの名前(Tabコントロール機能不足対応) private string? rclickTabName; - private readonly object syncObject = new object(); // ロック用 + private readonly object syncObject = new(); // ロック用 private const string DetailHtmlFormatHead = "" @@ -133,18 +133,18 @@ public partial class TweenMain : OTBaseForm private FormWindowState formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する // twitter解析部 - private readonly TwitterApi twitterApi = new TwitterApi(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); + private readonly TwitterApi twitterApi = new(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); private Twitter tw = null!; // Growl呼び出し部 - private readonly GrowlHelper gh = new GrowlHelper(ApplicationSettings.ApplicationName); + private readonly GrowlHelper gh = new(ApplicationSettings.ApplicationName); // サブ画面インスタンス /// 検索画面インスタンス - internal SearchWordDialog SearchDialog = new SearchWordDialog(); + internal SearchWordDialog SearchDialog = new(); - private readonly OpenURL urlDialog = new OpenURL(); + private readonly OpenURL urlDialog = new(); /// @id補助 public AtIdSupplement AtIdSupl = null!; @@ -246,13 +246,13 @@ public partial class TweenMain : OTBaseForm private Icon replyIcon = null!; private Icon replyIconBlink = null!; - private readonly ImageList listViewImageList = new ImageList(); // ListViewItemの高さ変更用 + private readonly ImageList listViewImageList = new(); // ListViewItemの高さ変更用 private PostClass? anchorPost; private bool anchorFlag; // true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画) /// 発言履歴 - private readonly List history = new List(); + private readonly List history = new(); /// 発言履歴カレントインデックス private int hisIdx; @@ -263,11 +263,11 @@ public partial class TweenMain : OTBaseForm private (long StatusId, string ScreenName)? inReplyTo = null; // 時速表示用 - private readonly List postTimestamps = new List(); - private readonly List favTimestamps = new List(); + private readonly List postTimestamps = new(); + private readonly List favTimestamps = new(); // 以下DrawItem関連 - private readonly SolidBrush brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight)); + private readonly SolidBrush brsHighLight = new(Color.FromKnownColor(KnownColor.Highlight)); private SolidBrush brsBackColorMine = null!; private SolidBrush brsBackColorAt = null!; private SolidBrush brsBackColorYou = null!; @@ -277,9 +277,9 @@ public partial class TweenMain : OTBaseForm private SolidBrush brsBackColorNone = null!; /// Listにフォーカスないときの選択行の背景色 - private readonly SolidBrush brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)); + private readonly SolidBrush brsDeactiveSelection = new(Color.FromKnownColor(KnownColor.ButtonFace)); - private readonly StringFormat sfTab = new StringFormat(); + private readonly StringFormat sfTab = new(); ////////////////////////////////////////////////////////////////////////////////////////////////////////// private TabInformations statuses = null!; @@ -343,8 +343,8 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ private bool isColumnChanged = false; private const int MaxWorderThreads = 20; - private readonly SemaphoreSlim workerSemaphore = new SemaphoreSlim(MaxWorderThreads); - private readonly CancellationTokenSource workerCts = new CancellationTokenSource(); + private readonly SemaphoreSlim workerSemaphore = new(MaxWorderThreads); + private readonly CancellationTokenSource workerCts = new(); private readonly IProgress workerProgress = null!; private int unreadCounter = -1; @@ -357,7 +357,7 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ ////////////////////////////////////////////////////////////////////////////////////////////////////////// - private readonly TimelineScheduler timelineScheduler = new TimelineScheduler(); + private readonly TimelineScheduler timelineScheduler = new(); private DebounceTimer selectionDebouncer = null!; private DebounceTimer saveConfigDebouncer = null!; @@ -392,7 +392,7 @@ public ReplyChain(long originalId, long inReplyToId, TabModel originalTab) private Stack? replyChains; /// ポスト選択履歴 - private readonly Stack<(TabModel, PostClass?)> selectPostChains = new Stack<(TabModel, PostClass?)>(); + private readonly Stack<(TabModel, PostClass?)> selectPostChains = new(); public TabModel CurrentTab => this.statuses.SelectedTab; @@ -5527,7 +5527,7 @@ public string CreateDetailHtml(string orgdata) private void DispSelectedPost() => this.DispSelectedPost(false); - private PostClass displayPost = new PostClass(); + private PostClass displayPost = new(); /// /// サムネイル表示に使用する CancellationToken の生成元 diff --git a/OpenTween/TweetExtractor.cs b/OpenTween/TweetExtractor.cs index f26eccd7e..9b1dfd946 100644 --- a/OpenTween/TweetExtractor.cs +++ b/OpenTween/TweetExtractor.cs @@ -34,7 +34,7 @@ namespace OpenTween { public static class TweetExtractor { - public static readonly Regex EmojiPattern = new Regex(@"(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f"); + public static readonly Regex EmojiPattern = new(@"(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f"); /// /// テキストから URL を抽出して返します diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index 6d6b00c1a..1fa4d49a9 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -43,8 +43,8 @@ namespace OpenTween { public partial class TweetThumbnail : UserControl { - protected internal List PictureBox = new List(); - protected MouseWheelMessageFilter filter = new MouseWheelMessageFilter(); + protected internal List PictureBox = new(); + protected MouseWheelMessageFilter filter = new(); public event EventHandler? ThumbnailLoading; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 56acd5348..1e5eccc3d 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -125,12 +125,12 @@ public class Twitter : IDisposable /// /// ツイートへのパーマリンクURLを判定する正規表現 /// - public static readonly Regex StatusUrlRegex = new Regex(@"https?://([^.]+\.)?twitter\.com/(#!/)?(?[a-zA-Z0-9_]+)/status(es)?/(?[0-9]+)(/photo)?", RegexOptions.IgnoreCase); + public static readonly Regex StatusUrlRegex = new(@"https?://([^.]+\.)?twitter\.com/(#!/)?(?[a-zA-Z0-9_]+)/status(es)?/(?[0-9]+)(/photo)?", RegexOptions.IgnoreCase); /// /// attachment_url に指定可能な URL を判定する正規表現 /// - public static readonly Regex AttachmentUrlRegex = new Regex( + public static readonly Regex AttachmentUrlRegex = new( @"https?://( twitter\.com/[0-9A-Za-z_]+/status/[0-9]+ | mobile\.twitter\.com/[0-9A-Za-z_]+/status/[0-9]+ @@ -141,7 +141,7 @@ public class Twitter : IDisposable /// /// FavstarやaclogなどTwitter関連サービスのパーマリンクURLからステータスIDを抽出する正規表現 /// - public static readonly Regex ThirdPartyStatusUrlRegex = new Regex( + public static readonly Regex ThirdPartyStatusUrlRegex = new( @"https?://(?:[^.]+\.)?(?: favstar\.fm/users/[a-zA-Z0-9_]+/status/ # Favstar | favstar\.fm/t/ # Favstar (short) @@ -153,7 +153,7 @@ public class Twitter : IDisposable /// /// DM送信かどうかを判定する正規表現 /// - public static readonly Regex DMSendTextRegex = new Regex(@"^DM? +(?[a-zA-Z0-9_]+) +(?.*)", RegexOptions.IgnoreCase | RegexOptions.Singleline); + public static readonly Regex DMSendTextRegex = new(@"^DM? +(?[a-zA-Z0-9_]+) +(?.*)", RegexOptions.IgnoreCase | RegexOptions.Singleline); public TwitterApi Api { get; } @@ -167,12 +167,12 @@ public class Twitter : IDisposable private delegate void GetIconImageDelegate(PostClass post); - private readonly object lockObj = new object(); + private readonly object lockObj = new(); private ISet followerId = new HashSet(); private long[] noRTId = Array.Empty(); // プロパティからアクセスされる共通情報 - private readonly List hashList = new List(); + private readonly List hashList = new(); private string? nextCursorDirectMessage = null; @@ -1571,7 +1571,7 @@ internal static string CreateHtmlAnchor(string text, TwitterEntities? entities, return text; } - private static readonly Uri SourceUriBase = new Uri("https://twitter.com/"); + private static readonly Uri SourceUriBase = new("https://twitter.com/"); /// /// Twitter APIから得たHTML形式のsource文字列を分析し、source名とURLに分離します From 87dfe775fa18a86f5cc018742796fafb4fdca524 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:29:22 +0900 Subject: [PATCH 133/402] =?UTF-8?q?switch=E5=BC=8F=E3=82=92=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=99=E3=82=8B=20(IDE0066)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Models/TabModel.cs | 22 ++++++---------------- OpenTween/Twitter.cs | 17 ++++++----------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index 1b16ccde3..8d8cd1167 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -238,23 +238,13 @@ private void ApplySortMode() } else { - Comparison postComparison; - switch (this.SortMode) + Comparison postComparison = this.SortMode switch { - default: - case ComparerMode.Data: - postComparison = (x, y) => Comparer.Default.Compare(x?.TextFromApi, y?.TextFromApi); - break; - case ComparerMode.Name: - postComparison = (x, y) => Comparer.Default.Compare(x?.ScreenName, y?.ScreenName); - break; - case ComparerMode.Nickname: - postComparison = (x, y) => Comparer.Default.Compare(x?.Nickname, y?.Nickname); - break; - case ComparerMode.Source: - postComparison = (x, y) => Comparer.Default.Compare(x?.Source, y?.Source); - break; - } + ComparerMode.Name => (x, y) => Comparer.Default.Compare(x?.ScreenName, y?.ScreenName), + ComparerMode.Nickname => (x, y) => Comparer.Default.Compare(x?.Nickname, y?.Nickname), + ComparerMode.Source => (x, y) => Comparer.Default.Compare(x?.Source, y?.Source), + _ => (x, y) => Comparer.Default.Compare(x?.TextFromApi, y?.TextFromApi), + }; comparison = (x, y) => { diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 1e5eccc3d..2b92d22b3 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1789,18 +1789,13 @@ int GetWeightFromCodepoint(int codepoint) /// public static string CreateProfileImageUrl(string normalUrl, string size) { - switch (size) + return size switch { - case "original": - return normalUrl.Replace("_normal.", "."); - case "normal": - return normalUrl; - case "bigger": - case "mini": - return normalUrl.Replace("_normal.", $"_{size}."); - default: - throw new ArgumentException($"Invalid size: ${size}", nameof(size)); - } + "original" => normalUrl.Replace("_normal.", "."), + "normal" => normalUrl, + "bigger" or "mini" => normalUrl.Replace("_normal.", $"_{size}."), + _ => throw new ArgumentException($"Invalid size: ${size}", nameof(size)), + }; } public static string DecideProfileImageSize(int sizePx) From 00cef14ad80be2fc9dad39080c77e304f5f4f10f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:13:07 +0900 Subject: [PATCH 134/402] =?UTF-8?q?using=20var=20=E3=82=92=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=99=E3=82=8B=20(IDE0063)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/MemoryImageTest.cs | 73 +-- OpenTween.Tests/OTBaseFormTest.cs | 92 ++- OpenTween.Tests/OTPictureBoxTest.cs | 92 ++- OpenTween.Tests/OTSplitContainerTest.cs | 559 ++++++++---------- OpenTween.Tests/ShortUrlTest.cs | 508 ++++++++-------- OpenTween.Tests/TabsDialogTest.cs | 130 ++-- OpenTween.Tests/TestUtils.cs | 12 +- .../Services/FoursquareCheckinTest.cs | 194 +++--- OpenTween.Tests/ToolStripAPIGaugeTest.cs | 180 +++--- OpenTween.Tests/TweenMainTest.cs | 38 +- OpenTween.Tests/TweetThumbnailTest.cs | 237 ++++---- 11 files changed, 980 insertions(+), 1135 deletions(-) diff --git a/OpenTween.Tests/MemoryImageTest.cs b/OpenTween.Tests/MemoryImageTest.cs index 2b406f9a7..4681b604c 100644 --- a/OpenTween.Tests/MemoryImageTest.cs +++ b/OpenTween.Tests/MemoryImageTest.cs @@ -36,72 +36,59 @@ public class MemoryImageTest [Fact] public async Task ImageFormat_GifTest() { - using (var imgStream = File.OpenRead("Resources/re.gif")) - using (var image = await MemoryImage.CopyFromStreamAsync(imgStream).ConfigureAwait(false)) - { - Assert.Equal(ImageFormat.Gif, image.ImageFormat); - Assert.Equal(".gif", image.ImageFormatExt); - } + using var imgStream = File.OpenRead("Resources/re.gif"); + using var image = await MemoryImage.CopyFromStreamAsync(imgStream).ConfigureAwait(false); + Assert.Equal(ImageFormat.Gif, image.ImageFormat); + Assert.Equal(".gif", image.ImageFormatExt); } [Fact] public void ImageFormat_CopyFromImageTest() { - using (var bitmap = new Bitmap(width: 200, height: 200)) - using (var image = MemoryImage.CopyFromImage(bitmap)) - { - // CopyFromImage から作成した MemoryImage は PNG 画像として扱われる - Assert.Equal(ImageFormat.Png, image.ImageFormat); - Assert.Equal(".png", image.ImageFormatExt); - } + using var bitmap = new Bitmap(width: 200, height: 200); + using var image = MemoryImage.CopyFromImage(bitmap); + + // CopyFromImage から作成した MemoryImage は PNG 画像として扱われる + Assert.Equal(ImageFormat.Png, image.ImageFormat); + Assert.Equal(".png", image.ImageFormatExt); } [Fact] public void CopyFromImage_Test() { - using (var bitmap = new Bitmap(width: 200, height: 200)) - { - // MemoryImage をエラー無く作成できることをテストする - using (var image = MemoryImage.CopyFromImage(bitmap)) - { - } - } + using var bitmap = new Bitmap(width: 200, height: 200); + + // MemoryImage をエラー無く作成できることをテストする + using var image = MemoryImage.CopyFromImage(bitmap); } [Fact] public void Dispose_Test() { - using (var image = TestUtils.CreateDummyImage()) - { - Assert.False(image.IsDisposed); + using var image = TestUtils.CreateDummyImage(); + Assert.False(image.IsDisposed); - image.Dispose(); + image.Dispose(); - Assert.True(image.IsDisposed); - Assert.Throws(() => image.Image); - Assert.Throws(() => image.ImageFormat); - } + Assert.True(image.IsDisposed); + Assert.Throws(() => image.Image); + Assert.Throws(() => image.ImageFormat); } [Fact] public async Task Equals_Test() { - using (var imgStream1 = File.OpenRead("Resources/re.gif")) - using (var image1 = await MemoryImage.CopyFromStreamAsync(imgStream1).ConfigureAwait(false)) - { - using (var imgStream2 = File.OpenRead("Resources/re.gif")) - using (var image2 = await MemoryImage.CopyFromStreamAsync(imgStream2).ConfigureAwait(false)) - { - Assert.True(image1.Equals(image2)); - Assert.True(image2.Equals(image1)); - } + using var imgStream1 = File.OpenRead("Resources/re.gif"); + using var image1 = await MemoryImage.CopyFromStreamAsync(imgStream1).ConfigureAwait(false); + + using var imgStream2 = File.OpenRead("Resources/re.gif"); + using var image2 = await MemoryImage.CopyFromStreamAsync(imgStream2).ConfigureAwait(false); + Assert.True(image1.Equals(image2)); + Assert.True(image2.Equals(image1)); - using (var image3 = TestUtils.CreateDummyImage()) - { - Assert.False(image1.Equals(image3)); - Assert.False(image3.Equals(image1)); - } - } + using var image3 = TestUtils.CreateDummyImage(); + Assert.False(image1.Equals(image3)); + Assert.False(image3.Equals(image1)); } } } diff --git a/OpenTween.Tests/OTBaseFormTest.cs b/OpenTween.Tests/OTBaseFormTest.cs index fc27c757c..e89f26148 100644 --- a/OpenTween.Tests/OTBaseFormTest.cs +++ b/OpenTween.Tests/OTBaseFormTest.cs @@ -45,97 +45,85 @@ protected void SetupSynchronizationContext() [Fact] public async Task InvokeAsync_Test() { - using (var form = new TestForm()) + using var form = new TestForm(); + await Task.Run(async () => { - await Task.Run(async () => - { - await form.InvokeAsync(() => form.Text = "hoge"); - }); + await form.InvokeAsync(() => form.Text = "hoge"); + }); - Assert.Equal("hoge", form.Text); - } + Assert.Equal("hoge", form.Text); } [Fact] public async Task InvokeAsync_ReturnValueTest() { - using (var form = new TestForm()) - { - form.Text = "hoge"; + using var form = new TestForm(); + form.Text = "hoge"; - await Task.Run(async () => - { - var ret = await form.InvokeAsync(() => form.Text); - Assert.Equal("hoge", ret); - }); - } + await Task.Run(async () => + { + var ret = await form.InvokeAsync(() => form.Text); + Assert.Equal("hoge", ret); + }); } [Fact] public async Task InvokeAsync_TaskTest() { - using (var form = new TestForm()) + using var form = new TestForm(); + await Task.Run(async () => { - await Task.Run(async () => + await form.InvokeAsync(async () => { - await form.InvokeAsync(async () => - { - await Task.Delay(1); - form.Text = "hoge"; - }); + await Task.Delay(1); + form.Text = "hoge"; }); + }); - Assert.Equal("hoge", form.Text); - } + Assert.Equal("hoge", form.Text); } [Fact] public async Task InvokeAsync_TaskWithValueTest() { - using (var form = new TestForm()) - { - form.Text = "hoge"; + using var form = new TestForm(); + form.Text = "hoge"; - await Task.Run(async () => + await Task.Run(async () => + { + var ret = await form.InvokeAsync(async () => { - var ret = await form.InvokeAsync(async () => - { - await Task.Delay(1); - return form.Text; - }); - - Assert.Equal("hoge", ret); + await Task.Delay(1); + return form.Text; }); - } + + Assert.Equal("hoge", ret); + }); } [Fact] public void ScaleChildControl_ListViewTest() { - using (var listview = new ListView { Width = 200, Height = 200 }) + using var listview = new ListView { Width = 200, Height = 200 }; + listview.Columns.AddRange(new[] { - listview.Columns.AddRange(new[] - { - new ColumnHeader { Width = 60 }, - new ColumnHeader { Width = 140 }, - }); + new ColumnHeader { Width = 60 }, + new ColumnHeader { Width = 140 }, + }); - OTBaseForm.ScaleChildControl(listview, new SizeF(1.25f, 1.25f)); + OTBaseForm.ScaleChildControl(listview, new SizeF(1.25f, 1.25f)); - Assert.Equal(75, listview.Columns[0].Width); - Assert.Equal(175, listview.Columns[1].Width); - } + Assert.Equal(75, listview.Columns[0].Width); + Assert.Equal(175, listview.Columns[1].Width); } [Fact] public void ScaleChildControl_VScrollBarTest() { - using (var scrollBar = new VScrollBar { Width = 20, Height = 200 }) - { - OTBaseForm.ScaleChildControl(scrollBar, new SizeF(2.0f, 2.0f)); + using var scrollBar = new VScrollBar { Width = 20, Height = 200 }; + OTBaseForm.ScaleChildControl(scrollBar, new SizeF(2.0f, 2.0f)); - Assert.Equal(40, scrollBar.Width); - } + Assert.Equal(40, scrollBar.Width); } } } diff --git a/OpenTween.Tests/OTPictureBoxTest.cs b/OpenTween.Tests/OTPictureBoxTest.cs index 2d154a793..6afa4f043 100644 --- a/OpenTween.Tests/OTPictureBoxTest.cs +++ b/OpenTween.Tests/OTPictureBoxTest.cs @@ -32,100 +32,90 @@ public class OTPictureBoxTest [Fact] public void SizeMode_SetterGetterTest() { - using (var picbox = new OTPictureBox()) - { - picbox.SizeMode = PictureBoxSizeMode.Zoom; + using var picbox = new OTPictureBox(); + picbox.SizeMode = PictureBoxSizeMode.Zoom; - Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); - Assert.Equal(PictureBoxSizeMode.Zoom, ((PictureBox)picbox).SizeMode); - } + Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); + Assert.Equal(PictureBoxSizeMode.Zoom, ((PictureBox)picbox).SizeMode); } [Fact] public void SizeMode_ErrorImageTest() { - using (var picbox = new OTPictureBox()) - { - picbox.SizeMode = PictureBoxSizeMode.Zoom; + using var picbox = new OTPictureBox(); + picbox.SizeMode = PictureBoxSizeMode.Zoom; - picbox.ShowErrorImage(); + picbox.ShowErrorImage(); - Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); - Assert.Equal(PictureBoxSizeMode.CenterImage, ((PictureBox)picbox).SizeMode); - } + Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); + Assert.Equal(PictureBoxSizeMode.CenterImage, ((PictureBox)picbox).SizeMode); } [Fact] public void SizeMode_ErrorImageTest2() { - using (var picbox = new OTPictureBox()) - { - picbox.ShowErrorImage(); + using var picbox = new OTPictureBox(); + picbox.ShowErrorImage(); - picbox.SizeMode = PictureBoxSizeMode.Zoom; + picbox.SizeMode = PictureBoxSizeMode.Zoom; - Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); - Assert.Equal(PictureBoxSizeMode.CenterImage, ((PictureBox)picbox).SizeMode); - } + Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); + Assert.Equal(PictureBoxSizeMode.CenterImage, ((PictureBox)picbox).SizeMode); } [Fact] public void SizeMode_RestoreTest() { - using (var picbox = new OTPictureBox()) - { - picbox.SizeMode = PictureBoxSizeMode.Zoom; + using var picbox = new OTPictureBox(); + picbox.SizeMode = PictureBoxSizeMode.Zoom; - picbox.ShowErrorImage(); + picbox.ShowErrorImage(); - picbox.Image = TestUtils.CreateDummyImage(); + picbox.Image = TestUtils.CreateDummyImage(); - Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); - Assert.Equal(PictureBoxSizeMode.Zoom, ((PictureBox)picbox).SizeMode); - } + Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); + Assert.Equal(PictureBoxSizeMode.Zoom, ((PictureBox)picbox).SizeMode); } [Fact] public async Task SetImageFromAsync_Test() { - using (var picbox = new OTPictureBox()) - { - // Mono でのテスト実行時にデッドロックする問題の対策 - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); + using var picbox = new OTPictureBox(); - var tcs = new TaskCompletionSource(); + // Mono でのテスト実行時にデッドロックする問題の対策 + SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var setImageTask = picbox.SetImageFromTask(() => tcs.Task); + var tcs = new TaskCompletionSource(); - Assert.Equal(picbox.InitialImage, ((PictureBox)picbox).Image); + var setImageTask = picbox.SetImageFromTask(() => tcs.Task); - var image = TestUtils.CreateDummyImage(); - tcs.SetResult(image); - await setImageTask; + Assert.Equal(picbox.InitialImage, ((PictureBox)picbox).Image); - Assert.Equal(image, picbox.Image); - } + var image = TestUtils.CreateDummyImage(); + tcs.SetResult(image); + await setImageTask; + + Assert.Equal(image, picbox.Image); } [Fact] public async Task SetImageFromAsync_ErrorTest() { - using (var picbox = new OTPictureBox()) - { - // Mono でのテスト実行時にデッドロックする問題の対策 - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); + using var picbox = new OTPictureBox(); + + // Mono でのテスト実行時にデッドロックする問題の対策 + SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); - var setImageTask = picbox.SetImageFromTask(() => tcs.Task); + var setImageTask = picbox.SetImageFromTask(() => tcs.Task); - Assert.Equal(picbox.InitialImage, ((PictureBox)picbox).Image); + Assert.Equal(picbox.InitialImage, ((PictureBox)picbox).Image); - tcs.SetException(new InvalidImageException()); - await setImageTask; + tcs.SetException(new InvalidImageException()); + await setImageTask; - Assert.Equal(picbox.ErrorImage, ((PictureBox)picbox).Image); - } + Assert.Equal(picbox.ErrorImage, ((PictureBox)picbox).Image); } } } diff --git a/OpenTween.Tests/OTSplitContainerTest.cs b/OpenTween.Tests/OTSplitContainerTest.cs index b70844388..c196dc671 100644 --- a/OpenTween.Tests/OTSplitContainerTest.cs +++ b/OpenTween.Tests/OTSplitContainerTest.cs @@ -35,255 +35,234 @@ public class OTSplitContainerTest [Fact] public void IsPanelInvertedGetter_Test() { - using (var splitContainer = new OTSplitContainer()) - { - Assert.False(splitContainer.IsPanelInverted); // デフォルト値 + using var splitContainer = new OTSplitContainer(); + Assert.False(splitContainer.IsPanelInverted); // デフォルト値 - splitContainer.IsPanelInverted = true; - Assert.True(splitContainer.IsPanelInverted); + splitContainer.IsPanelInverted = true; + Assert.True(splitContainer.IsPanelInverted); - splitContainer.IsPanelInverted = false; - Assert.False(splitContainer.IsPanelInverted); - } + splitContainer.IsPanelInverted = false; + Assert.False(splitContainer.IsPanelInverted); } [Fact] public void IsPanelInvertedSetter_InnerControlsTest() { - using (var splitContainer = new OTSplitContainer()) - using (var buttonA = new Button()) - using (var buttonB = new Button()) - using (var buttonC = new Button()) - using (var buttonD = new Button()) - { - splitContainer.Panel1.Controls.AddRange(new[] { buttonA, buttonB }); - splitContainer.Panel2.Controls.AddRange(new[] { buttonC, buttonD }); - - var baseSplitContainer = (SplitContainer)splitContainer; - - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.Equal(new[] { buttonA, buttonB }, baseSplitContainer.Panel1.Controls.Cast()); - Assert.Equal(new[] { buttonC, buttonD }, baseSplitContainer.Panel2.Controls.Cast()); - - // 上下パネルを反転する - splitContainer.IsPanelInverted = true; - - // Panel1, Panel2 内のコントロールが入れ替わる - Assert.Equal(new[] { buttonC, buttonD }, baseSplitContainer.Panel1.Controls.Cast()); - Assert.Equal(new[] { buttonA, buttonB }, baseSplitContainer.Panel2.Controls.Cast()); - - // 元に戻す - splitContainer.IsPanelInverted = false; - - // Panel1, Panel2 内のコントロールも元に戻る - Assert.Equal(new[] { buttonA, buttonB }, baseSplitContainer.Panel1.Controls.Cast()); - Assert.Equal(new[] { buttonC, buttonD }, baseSplitContainer.Panel2.Controls.Cast()); - } + using var splitContainer = new OTSplitContainer(); + using var buttonA = new Button(); + using var buttonB = new Button(); + using var buttonC = new Button(); + using var buttonD = new Button(); + + splitContainer.Panel1.Controls.AddRange(new[] { buttonA, buttonB }); + splitContainer.Panel2.Controls.AddRange(new[] { buttonC, buttonD }); + + var baseSplitContainer = (SplitContainer)splitContainer; + + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.Equal(new[] { buttonA, buttonB }, baseSplitContainer.Panel1.Controls.Cast()); + Assert.Equal(new[] { buttonC, buttonD }, baseSplitContainer.Panel2.Controls.Cast()); + + // 上下パネルを反転する + splitContainer.IsPanelInverted = true; + + // Panel1, Panel2 内のコントロールが入れ替わる + Assert.Equal(new[] { buttonC, buttonD }, baseSplitContainer.Panel1.Controls.Cast()); + Assert.Equal(new[] { buttonA, buttonB }, baseSplitContainer.Panel2.Controls.Cast()); + + // 元に戻す + splitContainer.IsPanelInverted = false; + + // Panel1, Panel2 内のコントロールも元に戻る + Assert.Equal(new[] { buttonA, buttonB }, baseSplitContainer.Panel1.Controls.Cast()); + Assert.Equal(new[] { buttonC, buttonD }, baseSplitContainer.Panel2.Controls.Cast()); } [Fact] public void IsPanelInvertedSetter_Panel1FixedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.FixedPanel = FixedPanel.Panel1; + using var splitContainer = new OTSplitContainer(); + splitContainer.FixedPanel = FixedPanel.Panel1; - var baseSplitContainer = (SplitContainer)splitContainer; + var baseSplitContainer = (SplitContainer)splitContainer; - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.Equal(FixedPanel.Panel1, baseSplitContainer.FixedPanel); + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.Equal(FixedPanel.Panel1, baseSplitContainer.FixedPanel); - // 上下パネルを反転する - splitContainer.IsPanelInverted = true; - Assert.Equal(FixedPanel.Panel2, baseSplitContainer.FixedPanel); + // 上下パネルを反転する + splitContainer.IsPanelInverted = true; + Assert.Equal(FixedPanel.Panel2, baseSplitContainer.FixedPanel); - // 元に戻す - splitContainer.IsPanelInverted = false; - Assert.Equal(FixedPanel.Panel1, baseSplitContainer.FixedPanel); - } + // 元に戻す + splitContainer.IsPanelInverted = false; + Assert.Equal(FixedPanel.Panel1, baseSplitContainer.FixedPanel); } [Fact] public void IsPanelInvertedSetter_Panel2FixedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.FixedPanel = FixedPanel.Panel2; + using var splitContainer = new OTSplitContainer(); + splitContainer.FixedPanel = FixedPanel.Panel2; - var baseSplitContainer = (SplitContainer)splitContainer; + var baseSplitContainer = (SplitContainer)splitContainer; - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.Equal(FixedPanel.Panel2, baseSplitContainer.FixedPanel); + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.Equal(FixedPanel.Panel2, baseSplitContainer.FixedPanel); - // 上下パネルを反転する - splitContainer.IsPanelInverted = true; - Assert.Equal(FixedPanel.Panel1, baseSplitContainer.FixedPanel); + // 上下パネルを反転する + splitContainer.IsPanelInverted = true; + Assert.Equal(FixedPanel.Panel1, baseSplitContainer.FixedPanel); - // 元に戻す - splitContainer.IsPanelInverted = false; - Assert.Equal(FixedPanel.Panel2, baseSplitContainer.FixedPanel); - } + // 元に戻す + splitContainer.IsPanelInverted = false; + Assert.Equal(FixedPanel.Panel2, baseSplitContainer.FixedPanel); } [Fact] public void IsPanelInvertedSetter_NoneFixedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.FixedPanel = FixedPanel.None; + using var splitContainer = new OTSplitContainer(); + splitContainer.FixedPanel = FixedPanel.None; - var baseSplitContainer = (SplitContainer)splitContainer; + var baseSplitContainer = (SplitContainer)splitContainer; - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.Equal(FixedPanel.None, baseSplitContainer.FixedPanel); + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.Equal(FixedPanel.None, baseSplitContainer.FixedPanel); - // 上下パネルを反転する - splitContainer.IsPanelInverted = true; - Assert.Equal(FixedPanel.None, baseSplitContainer.FixedPanel); + // 上下パネルを反転する + splitContainer.IsPanelInverted = true; + Assert.Equal(FixedPanel.None, baseSplitContainer.FixedPanel); - // 元に戻す - splitContainer.IsPanelInverted = false; - Assert.Equal(FixedPanel.None, baseSplitContainer.FixedPanel); - } + // 元に戻す + splitContainer.IsPanelInverted = false; + Assert.Equal(FixedPanel.None, baseSplitContainer.FixedPanel); } [Fact] public void IsPanelInvertedSetter_PanelMinSizeTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.Panel1MinSize = 200; - splitContainer.Panel2MinSize = 300; - - var baseSplitContainer = (SplitContainer)splitContainer; - - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.Equal(200, baseSplitContainer.Panel1MinSize); - Assert.Equal(300, baseSplitContainer.Panel2MinSize); - - // 上下パネルを反転する - splitContainer.IsPanelInverted = true; - Assert.Equal(300, baseSplitContainer.Panel1MinSize); - Assert.Equal(200, baseSplitContainer.Panel2MinSize); - - // 元に戻す - splitContainer.IsPanelInverted = false; - Assert.Equal(200, baseSplitContainer.Panel1MinSize); - Assert.Equal(300, baseSplitContainer.Panel2MinSize); - } + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.Panel1MinSize = 200; + splitContainer.Panel2MinSize = 300; + + var baseSplitContainer = (SplitContainer)splitContainer; + + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.Equal(200, baseSplitContainer.Panel1MinSize); + Assert.Equal(300, baseSplitContainer.Panel2MinSize); + + // 上下パネルを反転する + splitContainer.IsPanelInverted = true; + Assert.Equal(300, baseSplitContainer.Panel1MinSize); + Assert.Equal(200, baseSplitContainer.Panel2MinSize); + + // 元に戻す + splitContainer.IsPanelInverted = false; + Assert.Equal(200, baseSplitContainer.Panel1MinSize); + Assert.Equal(300, baseSplitContainer.Panel2MinSize); } [Fact] public void IsPanelInvertedSetter_Panel1CollapsedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.Panel1Collapsed = true; - - var baseSplitContainer = (SplitContainer)splitContainer; - - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.True(baseSplitContainer.Panel1Collapsed); - Assert.False(baseSplitContainer.Panel2Collapsed); - - // 上下パネルを反転する - splitContainer.IsPanelInverted = true; - Assert.False(baseSplitContainer.Panel1Collapsed); - Assert.True(baseSplitContainer.Panel2Collapsed); - - // 元に戻す - splitContainer.IsPanelInverted = false; - Assert.True(baseSplitContainer.Panel1Collapsed); - Assert.False(baseSplitContainer.Panel2Collapsed); - } + using var splitContainer = new OTSplitContainer(); + splitContainer.Panel1Collapsed = true; + + var baseSplitContainer = (SplitContainer)splitContainer; + + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.True(baseSplitContainer.Panel1Collapsed); + Assert.False(baseSplitContainer.Panel2Collapsed); + + // 上下パネルを反転する + splitContainer.IsPanelInverted = true; + Assert.False(baseSplitContainer.Panel1Collapsed); + Assert.True(baseSplitContainer.Panel2Collapsed); + + // 元に戻す + splitContainer.IsPanelInverted = false; + Assert.True(baseSplitContainer.Panel1Collapsed); + Assert.False(baseSplitContainer.Panel2Collapsed); } [Fact] public void IsPanelInvertedSetter_Panel2CollapsedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.Panel2Collapsed = true; - - var baseSplitContainer = (SplitContainer)splitContainer; - - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.False(baseSplitContainer.Panel1Collapsed); - Assert.True(baseSplitContainer.Panel2Collapsed); - - // 上下パネルを反転する - splitContainer.IsPanelInverted = true; - Assert.True(baseSplitContainer.Panel1Collapsed); - Assert.False(baseSplitContainer.Panel2Collapsed); - - // 元に戻す - splitContainer.IsPanelInverted = false; - Assert.False(baseSplitContainer.Panel1Collapsed); - Assert.True(baseSplitContainer.Panel2Collapsed); - } + using var splitContainer = new OTSplitContainer(); + splitContainer.Panel2Collapsed = true; + + var baseSplitContainer = (SplitContainer)splitContainer; + + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.False(baseSplitContainer.Panel1Collapsed); + Assert.True(baseSplitContainer.Panel2Collapsed); + + // 上下パネルを反転する + splitContainer.IsPanelInverted = true; + Assert.True(baseSplitContainer.Panel1Collapsed); + Assert.False(baseSplitContainer.Panel2Collapsed); + + // 元に戻す + splitContainer.IsPanelInverted = false; + Assert.False(baseSplitContainer.Panel1Collapsed); + Assert.True(baseSplitContainer.Panel2Collapsed); } [Fact] public void IsPanelInvertedSetter_SplitterDistanceHorizontalTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.Orientation = Orientation.Horizontal; // 上下に分割された状態 - splitContainer.SplitterWidth = 5; // 分割線の幅は 5px - splitContainer.SplitterDistance = 500; // 上から 500px で分割 (下から 300px - 5px) + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.Orientation = Orientation.Horizontal; // 上下に分割された状態 + splitContainer.SplitterWidth = 5; // 分割線の幅は 5px + splitContainer.SplitterDistance = 500; // 上から 500px で分割 (下から 300px - 5px) - var baseSplitContainer = (SplitContainer)splitContainer; + var baseSplitContainer = (SplitContainer)splitContainer; - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.Equal(500, baseSplitContainer.SplitterDistance); + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.Equal(500, baseSplitContainer.SplitterDistance); - // 上下パネルを反転する - splitContainer.IsPanelInverted = true; - Assert.Equal(95, baseSplitContainer.SplitterDistance); // 上から 100px - 5px (下から 500px) + // 上下パネルを反転する + splitContainer.IsPanelInverted = true; + Assert.Equal(95, baseSplitContainer.SplitterDistance); // 上から 100px - 5px (下から 500px) - // 元に戻す - splitContainer.IsPanelInverted = false; - Assert.Equal(500, baseSplitContainer.SplitterDistance); - } + // 元に戻す + splitContainer.IsPanelInverted = false; + Assert.Equal(500, baseSplitContainer.SplitterDistance); } [Fact] public void IsPanelInvertedSetter_SplitterDistanceVerticalTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.Orientation = Orientation.Vertical; // 左右に分割された状態 - splitContainer.SplitterWidth = 5; // 分割線の幅は 5px - splitContainer.SplitterDistance = 500; // 左から 500px で分割 (右から 300px - 5px) + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.Orientation = Orientation.Vertical; // 左右に分割された状態 + splitContainer.SplitterWidth = 5; // 分割線の幅は 5px + splitContainer.SplitterDistance = 500; // 左から 500px で分割 (右から 300px - 5px) - var baseSplitContainer = (SplitContainer)splitContainer; + var baseSplitContainer = (SplitContainer)splitContainer; - // 反転前の状態 (通常の SplitContainer と同じ挙動) - Assert.Equal(500, baseSplitContainer.SplitterDistance); + // 反転前の状態 (通常の SplitContainer と同じ挙動) + Assert.Equal(500, baseSplitContainer.SplitterDistance); - // 左右パネルを反転する - splitContainer.IsPanelInverted = true; - Assert.Equal(295, baseSplitContainer.SplitterDistance); // 左から 300px - 5px (右から 500px) + // 左右パネルを反転する + splitContainer.IsPanelInverted = true; + Assert.Equal(295, baseSplitContainer.SplitterDistance); // 左から 300px - 5px (右から 500px) - // 元に戻す - splitContainer.IsPanelInverted = false; - Assert.Equal(500, baseSplitContainer.SplitterDistance); - } + // 元に戻す + splitContainer.IsPanelInverted = false; + Assert.Equal(500, baseSplitContainer.SplitterDistance); } [Fact] public void PanelGetter_InvertedTest() { - using (var splitContainer = new OTSplitContainer()) - { - var panel1 = splitContainer.Panel1; - var panel2 = splitContainer.Panel2; + using var splitContainer = new OTSplitContainer(); + var panel1 = splitContainer.Panel1; + var panel2 = splitContainer.Panel2; - splitContainer.IsPanelInverted = true; + splitContainer.IsPanelInverted = true; - Assert.Same(panel2, splitContainer.Panel1); - Assert.Same(panel1, splitContainer.Panel2); - } + Assert.Same(panel2, splitContainer.Panel1); + Assert.Same(panel1, splitContainer.Panel2); } [Theory] @@ -292,16 +271,14 @@ public void PanelGetter_InvertedTest() [InlineData(FixedPanel.Panel2)] public void FixedPanelGetter_InvertedTest(FixedPanel fixedPanel) { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.FixedPanel = fixedPanel; + using var splitContainer = new OTSplitContainer(); + splitContainer.FixedPanel = fixedPanel; - Assert.Equal(fixedPanel, splitContainer.FixedPanel); + Assert.Equal(fixedPanel, splitContainer.FixedPanel); - // 反転した状態でも OTSplitterContainer.FixedPanel の値は外見上変化しない - splitContainer.IsPanelInverted = true; - Assert.Equal(fixedPanel, splitContainer.FixedPanel); - } + // 反転した状態でも OTSplitterContainer.FixedPanel の値は外見上変化しない + splitContainer.IsPanelInverted = true; + Assert.Equal(fixedPanel, splitContainer.FixedPanel); } [Theory] @@ -310,179 +287,157 @@ public void FixedPanelGetter_InvertedTest(FixedPanel fixedPanel) [InlineData(FixedPanel.Panel2, FixedPanel.Panel1)] public void FixedPanelSetter_InvertedTest(FixedPanel inputValue, FixedPanel internalValue) { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.IsPanelInverted = true; - - // 反転中に FixedPanel を変更する - splitContainer.FixedPanel = inputValue; - Assert.Equal(internalValue, ((SplitContainer)splitContainer).FixedPanel); - } + using var splitContainer = new OTSplitContainer(); + splitContainer.IsPanelInverted = true; + + // 反転中に FixedPanel を変更する + splitContainer.FixedPanel = inputValue; + Assert.Equal(internalValue, ((SplitContainer)splitContainer).FixedPanel); } [Fact] public void SplitterDistanceGetter_InvertedVerticalTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.Orientation = Orientation.Vertical; - splitContainer.SplitterWidth = 5; - splitContainer.SplitterDistance = 500; - - // setter で代入した長さと一致しているか、SplitterDistance と Panel1.Width が一致しているかをテスト - Assert.Equal(500, splitContainer.SplitterDistance); - Assert.Equal(splitContainer.Panel1.Width, splitContainer.SplitterDistance); - - // 反転した状態でも OTSplitterContainer.SplitterDistance の値は外見上変化しない - splitContainer.IsPanelInverted = true; - Assert.Equal(500, splitContainer.SplitterDistance); - Assert.Equal(splitContainer.Panel1.Width, splitContainer.SplitterDistance); - } + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.Orientation = Orientation.Vertical; + splitContainer.SplitterWidth = 5; + splitContainer.SplitterDistance = 500; + + // setter で代入した長さと一致しているか、SplitterDistance と Panel1.Width が一致しているかをテスト + Assert.Equal(500, splitContainer.SplitterDistance); + Assert.Equal(splitContainer.Panel1.Width, splitContainer.SplitterDistance); + + // 反転した状態でも OTSplitterContainer.SplitterDistance の値は外見上変化しない + splitContainer.IsPanelInverted = true; + Assert.Equal(500, splitContainer.SplitterDistance); + Assert.Equal(splitContainer.Panel1.Width, splitContainer.SplitterDistance); } [Fact] public void SplitterDistanceGetter_InvertedHorizontalTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.Orientation = Orientation.Horizontal; - splitContainer.SplitterWidth = 5; - splitContainer.SplitterDistance = 500; - - // setter で代入した長さと一致しているか、SplitterDistance と Panel1.Height が一致しているかをテスト - Assert.Equal(500, splitContainer.SplitterDistance); - Assert.Equal(splitContainer.Panel1.Height, splitContainer.SplitterDistance); - - // 反転した状態でも OTSplitterContainer.SplitterDistance の値は外見上変化しない - splitContainer.IsPanelInverted = true; - Assert.Equal(500, splitContainer.SplitterDistance); - Assert.Equal(splitContainer.Panel1.Height, splitContainer.SplitterDistance); - } + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.Orientation = Orientation.Horizontal; + splitContainer.SplitterWidth = 5; + splitContainer.SplitterDistance = 500; + + // setter で代入した長さと一致しているか、SplitterDistance と Panel1.Height が一致しているかをテスト + Assert.Equal(500, splitContainer.SplitterDistance); + Assert.Equal(splitContainer.Panel1.Height, splitContainer.SplitterDistance); + + // 反転した状態でも OTSplitterContainer.SplitterDistance の値は外見上変化しない + splitContainer.IsPanelInverted = true; + Assert.Equal(500, splitContainer.SplitterDistance); + Assert.Equal(splitContainer.Panel1.Height, splitContainer.SplitterDistance); } [Fact] public void SplitterDistanceSetter_InvertedVerticalTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.Orientation = Orientation.Vertical; - splitContainer.SplitterWidth = 5; - - splitContainer.IsPanelInverted = true; - - // 反転中に SplitterDistance を変更する - splitContainer.SplitterDistance = 500; - Assert.Equal(295, ((SplitContainer)splitContainer).SplitterDistance); - Assert.Equal(500, ((SplitContainer)splitContainer).Panel2.Width); - } + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.Orientation = Orientation.Vertical; + splitContainer.SplitterWidth = 5; + + splitContainer.IsPanelInverted = true; + + // 反転中に SplitterDistance を変更する + splitContainer.SplitterDistance = 500; + Assert.Equal(295, ((SplitContainer)splitContainer).SplitterDistance); + Assert.Equal(500, ((SplitContainer)splitContainer).Panel2.Width); } [Fact] public void SplitterDistanceSetter_InvertedHorizontalTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.Orientation = Orientation.Horizontal; - splitContainer.SplitterWidth = 5; - - splitContainer.IsPanelInverted = true; - - // 反転中に SplitterDistance を変更する - splitContainer.SplitterDistance = 500; - Assert.Equal(95, ((SplitContainer)splitContainer).SplitterDistance); - Assert.Equal(500, ((SplitContainer)splitContainer).Panel2.Height); - } + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.Orientation = Orientation.Horizontal; + splitContainer.SplitterWidth = 5; + + splitContainer.IsPanelInverted = true; + + // 反転中に SplitterDistance を変更する + splitContainer.SplitterDistance = 500; + Assert.Equal(95, ((SplitContainer)splitContainer).SplitterDistance); + Assert.Equal(500, ((SplitContainer)splitContainer).Panel2.Height); } [Fact] public void PanelMinSizeGetter_InvertedTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.Panel1MinSize = 200; - splitContainer.Panel2MinSize = 300; - - Assert.Equal(200, splitContainer.Panel1MinSize); - Assert.Equal(300, splitContainer.Panel2MinSize); - - // 反転した状態でも OTSplitterContainer.Panel1MinSize, Panel2MinSize の値は外見上変化しない - splitContainer.IsPanelInverted = true; - Assert.Equal(200, splitContainer.Panel1MinSize); - Assert.Equal(300, splitContainer.Panel2MinSize); - } + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.Panel1MinSize = 200; + splitContainer.Panel2MinSize = 300; + + Assert.Equal(200, splitContainer.Panel1MinSize); + Assert.Equal(300, splitContainer.Panel2MinSize); + + // 反転した状態でも OTSplitterContainer.Panel1MinSize, Panel2MinSize の値は外見上変化しない + splitContainer.IsPanelInverted = true; + Assert.Equal(200, splitContainer.Panel1MinSize); + Assert.Equal(300, splitContainer.Panel2MinSize); } [Fact] public void PanelMinSizeSetter_InvertedTest() { - using (var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }) - { - splitContainer.IsPanelInverted = true; - - // 反転中に Panel1MinSize, Panel2MinSize を変更する - splitContainer.Panel1MinSize = 200; - splitContainer.Panel2MinSize = 300; - Assert.Equal(300, ((SplitContainer)splitContainer).Panel1MinSize); - Assert.Equal(200, ((SplitContainer)splitContainer).Panel2MinSize); - } + using var splitContainer = new OTSplitContainer { Width = 800, Height = 600 }; + splitContainer.IsPanelInverted = true; + + // 反転中に Panel1MinSize, Panel2MinSize を変更する + splitContainer.Panel1MinSize = 200; + splitContainer.Panel2MinSize = 300; + Assert.Equal(300, ((SplitContainer)splitContainer).Panel1MinSize); + Assert.Equal(200, ((SplitContainer)splitContainer).Panel2MinSize); } [Fact] public void Panel1CollapsedGetter_InvertedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.Panel1Collapsed = true; + using var splitContainer = new OTSplitContainer(); + splitContainer.Panel1Collapsed = true; - Assert.True(splitContainer.Panel1Collapsed); + Assert.True(splitContainer.Panel1Collapsed); - // 反転した状態でも OTSplitterContainer.Panel1Collapsed の値は外見上変化しない - splitContainer.IsPanelInverted = true; - Assert.True(splitContainer.Panel1Collapsed); - } + // 反転した状態でも OTSplitterContainer.Panel1Collapsed の値は外見上変化しない + splitContainer.IsPanelInverted = true; + Assert.True(splitContainer.Panel1Collapsed); } [Fact] public void Panel1CollapsedSetter_InvertedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.IsPanelInverted = true; - - // 反転中に Panel1Collapsed を変更する - splitContainer.Panel1Collapsed = true; - Assert.False(((SplitContainer)splitContainer).Panel1Collapsed); - Assert.True(((SplitContainer)splitContainer).Panel2Collapsed); - } + using var splitContainer = new OTSplitContainer(); + splitContainer.IsPanelInverted = true; + + // 反転中に Panel1Collapsed を変更する + splitContainer.Panel1Collapsed = true; + Assert.False(((SplitContainer)splitContainer).Panel1Collapsed); + Assert.True(((SplitContainer)splitContainer).Panel2Collapsed); } [Fact] public void Panel2CollapsedGetter_InvertedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.Panel2Collapsed = true; + using var splitContainer = new OTSplitContainer(); + splitContainer.Panel2Collapsed = true; - Assert.True(splitContainer.Panel2Collapsed); + Assert.True(splitContainer.Panel2Collapsed); - // 反転した状態でも OTSplitterContainer.Panel2Collapsed の値は外見上変化しない - splitContainer.IsPanelInverted = true; - Assert.True(splitContainer.Panel2Collapsed); - } + // 反転した状態でも OTSplitterContainer.Panel2Collapsed の値は外見上変化しない + splitContainer.IsPanelInverted = true; + Assert.True(splitContainer.Panel2Collapsed); } [Fact] public void Panel2CollapsedSetter_InvertedTest() { - using (var splitContainer = new OTSplitContainer()) - { - splitContainer.IsPanelInverted = true; - - // 反転中に Panel2Collapsed を変更する - splitContainer.Panel2Collapsed = true; - Assert.True(((SplitContainer)splitContainer).Panel1Collapsed); - Assert.False(((SplitContainer)splitContainer).Panel2Collapsed); - } + using var splitContainer = new OTSplitContainer(); + splitContainer.IsPanelInverted = true; + + // 反転中に Panel2Collapsed を変更する + splitContainer.Panel2Collapsed = true; + Assert.True(((SplitContainer)splitContainer).Panel1Collapsed); + Assert.False(((SplitContainer)splitContainer).Panel2Collapsed); } } } diff --git a/OpenTween.Tests/ShortUrlTest.cs b/OpenTween.Tests/ShortUrlTest.cs index a5a490ad9..887222617 100644 --- a/OpenTween.Tests/ShortUrlTest.cs +++ b/OpenTween.Tests/ShortUrlTest.cs @@ -38,392 +38,362 @@ public class ShortUrlTest public async Task ExpandUrlAsync_Test() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // https://t.co/hoge1 -> http://example.com/hoge2 - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); + // https://t.co/hoge1 -> http://example.com/hoge2 + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); - return this.CreateRedirectResponse("http://example.com/hoge2"); - }); + return this.CreateRedirectResponse("http://example.com/hoge2"); + }); - Assert.Equal(new Uri("http://example.com/hoge2"), - await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"))); + Assert.Equal(new Uri("http://example.com/hoge2"), + await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"))); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_IrregularUrlTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // https://www.flickr.com/photo.gne?short=hoge -> /photos/foo/11111/ - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://www.flickr.com/photo.gne?short=hoge"), x.RequestUri); + // https://www.flickr.com/photo.gne?short=hoge -> /photos/foo/11111/ + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://www.flickr.com/photo.gne?short=hoge"), x.RequestUri); - return this.CreateRedirectResponse("/photos/foo/11111/", UriKind.Relative); - }); + return this.CreateRedirectResponse("/photos/foo/11111/", UriKind.Relative); + }); - Assert.Equal(new Uri("https://www.flickr.com/photos/foo/11111/"), - await shortUrl.ExpandUrlAsync(new Uri("https://www.flickr.com/photo.gne?short=hoge"))); + Assert.Equal(new Uri("https://www.flickr.com/photos/foo/11111/"), + await shortUrl.ExpandUrlAsync(new Uri("https://www.flickr.com/photo.gne?short=hoge"))); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_DisableExpandingTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - shortUrl.DisableExpanding = true; + shortUrl.DisableExpanding = true; - // https://t.co/hoge1 -> http://example.com/hoge2 - handler.Enqueue(x => - { - // このリクエストは実行されないはず - Assert.True(false); - return this.CreateRedirectResponse("http://example.com/hoge2"); - }); + // https://t.co/hoge1 -> http://example.com/hoge2 + handler.Enqueue(x => + { + // このリクエストは実行されないはず + Assert.True(false); + return this.CreateRedirectResponse("http://example.com/hoge2"); + }); - Assert.Equal(new Uri("https://t.co/hoge1"), - await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"))); + Assert.Equal(new Uri("https://t.co/hoge1"), + await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"))); - Assert.Equal(1, handler.QueueCount); - } + Assert.Equal(1, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_RecursiveTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // https://t.co/hoge1 -> https://bit.ly/hoge2 - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); + // https://t.co/hoge1 -> https://bit.ly/hoge2 + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); - return this.CreateRedirectResponse("https://bit.ly/hoge2"); - }); + return this.CreateRedirectResponse("https://bit.ly/hoge2"); + }); - // https://bit.ly/hoge2 -> http://example.com/hoge3 - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://bit.ly/hoge2"), x.RequestUri); + // https://bit.ly/hoge2 -> http://example.com/hoge3 + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://bit.ly/hoge2"), x.RequestUri); - return this.CreateRedirectResponse("http://example.com/hoge3"); - }); + return this.CreateRedirectResponse("http://example.com/hoge3"); + }); - Assert.Equal(new Uri("http://example.com/hoge3"), - await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"))); + Assert.Equal(new Uri("http://example.com/hoge3"), + await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"))); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_RecursiveLimitTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // https://t.co/hoge1 -> https://bit.ly/hoge2 - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); + // https://t.co/hoge1 -> https://bit.ly/hoge2 + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); - return this.CreateRedirectResponse("https://bit.ly/hoge2"); - }); + return this.CreateRedirectResponse("https://bit.ly/hoge2"); + }); - // https://bit.ly/hoge2 -> https://tinyurl.com/hoge3 - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://bit.ly/hoge2"), x.RequestUri); + // https://bit.ly/hoge2 -> https://tinyurl.com/hoge3 + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://bit.ly/hoge2"), x.RequestUri); - return this.CreateRedirectResponse("https://tinyurl.com/hoge3"); - }); + return this.CreateRedirectResponse("https://tinyurl.com/hoge3"); + }); - // https://tinyurl.com/hoge3 -> http://example.com/hoge4 - handler.Enqueue(x => - { - // このリクエストは実行されないはず - Assert.True(false); - return this.CreateRedirectResponse("http://example.com/hoge4"); - }); + // https://tinyurl.com/hoge3 -> http://example.com/hoge4 + handler.Enqueue(x => + { + // このリクエストは実行されないはず + Assert.True(false); + return this.CreateRedirectResponse("http://example.com/hoge4"); + }); - Assert.Equal(new Uri("https://tinyurl.com/hoge3"), - await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"), redirectLimit: 2)); + Assert.Equal(new Uri("https://tinyurl.com/hoge3"), + await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"), redirectLimit: 2)); - Assert.Equal(1, handler.QueueCount); - } + Assert.Equal(1, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_UpgradeToHttpsTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // http://t.co/hoge -> http://example.com/hoge - handler.Enqueue(x => - { - // https:// に変換されてリクエストが送信される - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/hoge"), x.RequestUri); + // http://t.co/hoge -> http://example.com/hoge + handler.Enqueue(x => + { + // https:// に変換されてリクエストが送信される + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/hoge"), x.RequestUri); - return this.CreateRedirectResponse("http://example.com/hoge"); - }); + return this.CreateRedirectResponse("http://example.com/hoge"); + }); - Assert.Equal(new Uri("http://example.com/hoge"), - await shortUrl.ExpandUrlAsync(new Uri("http://t.co/hoge"))); + Assert.Equal(new Uri("http://example.com/hoge"), + await shortUrl.ExpandUrlAsync(new Uri("http://t.co/hoge"))); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_InsecureDomainTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // http://tinami.jp/hoge -> http://example.com/hoge - handler.Enqueue(x => - { - // HTTPS非対応のドメインは http:// のままリクエストが送信される - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("http://tinami.jp/hoge"), x.RequestUri); + // http://tinami.jp/hoge -> http://example.com/hoge + handler.Enqueue(x => + { + // HTTPS非対応のドメインは http:// のままリクエストが送信される + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("http://tinami.jp/hoge"), x.RequestUri); - return this.CreateRedirectResponse("http://example.com/hoge"); - }); + return this.CreateRedirectResponse("http://example.com/hoge"); + }); - Assert.Equal(new Uri("http://example.com/hoge"), - await shortUrl.ExpandUrlAsync(new Uri("http://tinami.jp/hoge"))); + Assert.Equal(new Uri("http://example.com/hoge"), + await shortUrl.ExpandUrlAsync(new Uri("http://tinami.jp/hoge"))); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_RelativeUriTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - handler.Enqueue(x => - { - // このリクエストは実行されないはず - Assert.True(false); - return this.CreateRedirectResponse(""); - }); + handler.Enqueue(x => + { + // このリクエストは実行されないはず + Assert.True(false); + return this.CreateRedirectResponse(""); + }); - // 相対 URI に対しては何も行わない - Assert.Equal(new Uri("./foo/bar", UriKind.Relative), - await shortUrl.ExpandUrlAsync(new Uri("./foo/bar", UriKind.Relative))); + // 相対 URI に対しては何も行わない + Assert.Equal(new Uri("./foo/bar", UriKind.Relative), + await shortUrl.ExpandUrlAsync(new Uri("./foo/bar", UriKind.Relative))); - Assert.Equal(1, handler.QueueCount); - } + Assert.Equal(1, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_RelativeRedirectTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // Location に相対 URL を指定したリダイレクト (テストに使う URL は適当) - // https://t.co/hogehoge -> /tetetete - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/hogehoge"), x.RequestUri); + // Location に相対 URL を指定したリダイレクト (テストに使う URL は適当) + // https://t.co/hogehoge -> /tetetete + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/hogehoge"), x.RequestUri); - return this.CreateRedirectResponse("/tetetete", UriKind.Relative); - }); + return this.CreateRedirectResponse("/tetetete", UriKind.Relative); + }); - // https://t.co/tetetete -> http://example.com/tetetete - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/tetetete"), x.RequestUri); + // https://t.co/tetetete -> http://example.com/tetetete + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/tetetete"), x.RequestUri); - return this.CreateRedirectResponse("http://example.com/tetetete"); - }); + return this.CreateRedirectResponse("http://example.com/tetetete"); + }); - Assert.Equal(new Uri("http://example.com/tetetete"), - await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hogehoge"))); + Assert.Equal(new Uri("http://example.com/tetetete"), + await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hogehoge"))); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_String_Test() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // https://t.co/hoge1 -> http://example.com/hoge2 - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); + // https://t.co/hoge1 -> http://example.com/hoge2 + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); - return this.CreateRedirectResponse("http://example.com/hoge2"); - }); + return this.CreateRedirectResponse("http://example.com/hoge2"); + }); - Assert.Equal("http://example.com/hoge2", - await shortUrl.ExpandUrlAsync("https://t.co/hoge1")); + Assert.Equal("http://example.com/hoge2", + await shortUrl.ExpandUrlAsync("https://t.co/hoge1")); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_String_SchemeLessUrlTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // https://t.co/hoge1 -> http://example.com/hoge2 - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); + // https://t.co/hoge1 -> http://example.com/hoge2 + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); - return this.CreateRedirectResponse("http://example.com/hoge2"); - }); + return this.CreateRedirectResponse("http://example.com/hoge2"); + }); - // スキームが省略されたURL - Assert.Equal("http://example.com/hoge2", - await shortUrl.ExpandUrlAsync("t.co/hoge1")); + // スキームが省略されたURL + Assert.Equal("http://example.com/hoge2", + await shortUrl.ExpandUrlAsync("t.co/hoge1")); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_String_InvalidUrlTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - handler.Enqueue(x => - { - // リクエストは送信されないはず - Assert.True(false); - return this.CreateRedirectResponse("http://example.com/hoge2"); - }); + handler.Enqueue(x => + { + // リクエストは送信されないはず + Assert.True(false); + return this.CreateRedirectResponse("http://example.com/hoge2"); + }); - // 不正なURL - Assert.Equal("..hogehoge..", await shortUrl.ExpandUrlAsync("..hogehoge..")); + // 不正なURL + Assert.Equal("..hogehoge..", await shortUrl.ExpandUrlAsync("..hogehoge..")); - Assert.Equal(1, handler.QueueCount); - } + Assert.Equal(1, handler.QueueCount); } [Fact] public async Task ExpandUrlAsync_HttpErrorTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // https://t.co/hoge1 -> 503 Service Unavailable - handler.Enqueue(x => - { - return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable); - }); + // https://t.co/hoge1 -> 503 Service Unavailable + handler.Enqueue(x => + { + return new HttpResponseMessage(HttpStatusCode.ServiceUnavailable); + }); - Assert.Equal(new Uri("https://t.co/hoge1"), - await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"))); + Assert.Equal(new Uri("https://t.co/hoge1"), + await shortUrl.ExpandUrlAsync(new Uri("https://t.co/hoge1"))); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlHtmlAsync_Test() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - // https://t.co/hoge1 -> http://example.com/hoge2 - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Head, x.Method); - Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); + // https://t.co/hoge1 -> http://example.com/hoge2 + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Head, x.Method); + Assert.Equal(new Uri("https://t.co/hoge1"), x.RequestUri); - return this.CreateRedirectResponse("http://example.com/hoge2"); - }); + return this.CreateRedirectResponse("http://example.com/hoge2"); + }); - Assert.Equal("hogehoge", - await shortUrl.ExpandUrlHtmlAsync("hogehoge")); + Assert.Equal("hogehoge", + await shortUrl.ExpandUrlHtmlAsync("hogehoge")); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ExpandUrlHtmlAsync_RelativeUriTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var shortUrl = new ShortUrl(http); + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); - handler.Enqueue(x => - { - // リクエストは送信されないはず - Assert.True(false); - return this.CreateRedirectResponse("http://example.com/hoge"); - }); + handler.Enqueue(x => + { + // リクエストは送信されないはず + Assert.True(false); + return this.CreateRedirectResponse("http://example.com/hoge"); + }); - Assert.Equal("hogehoge", - await shortUrl.ExpandUrlHtmlAsync("hogehoge")); + Assert.Equal("hogehoge", + await shortUrl.ExpandUrlHtmlAsync("hogehoge")); - Assert.Equal(1, handler.QueueCount); - } + Assert.Equal(1, handler.QueueCount); } private HttpResponseMessage CreateRedirectResponse(string uriStr) @@ -440,54 +410,50 @@ private HttpResponseMessage CreateRedirectResponse(string uriStr, UriKind uriKin public async Task ShortenUrlAsync_TinyUrlTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); + + handler.Enqueue(async x => { - var shortUrl = new ShortUrl(http); + Assert.Equal(HttpMethod.Post, x.Method); + Assert.Equal(new Uri("https://tinyurl.com/api-create.php"), x.RequestUri); + Assert.Equal("url=http%3A%2F%2Fexample.com%2Fhogehogehoge", await x.Content.ReadAsStringAsync()); - handler.Enqueue(async x => + return new HttpResponseMessage(HttpStatusCode.OK) { - Assert.Equal(HttpMethod.Post, x.Method); - Assert.Equal(new Uri("https://tinyurl.com/api-create.php"), x.RequestUri); - Assert.Equal("url=http%3A%2F%2Fexample.com%2Fhogehogehoge", await x.Content.ReadAsStringAsync()); + Content = new ByteArrayContent(Encoding.UTF8.GetBytes("http://tinyurl.com/hoge")), + }; + }); - return new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new ByteArrayContent(Encoding.UTF8.GetBytes("http://tinyurl.com/hoge")), - }; - }); + Assert.Equal(new Uri("https://tinyurl.com/hoge"), + await shortUrl.ShortenUrlAsync(MyCommon.UrlConverter.TinyUrl, new Uri("http://example.com/hogehogehoge"))); - Assert.Equal(new Uri("https://tinyurl.com/hoge"), - await shortUrl.ShortenUrlAsync(MyCommon.UrlConverter.TinyUrl, new Uri("http://example.com/hogehogehoge"))); - - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task ShortenUrlAsync_UxnuUrlTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) + using var http = new HttpClient(handler); + var shortUrl = new ShortUrl(http); + + handler.Enqueue(x => { - var shortUrl = new ShortUrl(http); + Assert.Equal(HttpMethod.Get, x.Method); + Assert.Equal("https://ux.nu/api/short?format=plain&url=http:%2F%2Fexample.com%2Fhogehoge", + x.RequestUri.AbsoluteUri); - handler.Enqueue(x => + return new HttpResponseMessage(HttpStatusCode.OK) { - Assert.Equal(HttpMethod.Get, x.Method); - Assert.Equal("https://ux.nu/api/short?format=plain&url=http:%2F%2Fexample.com%2Fhogehoge", - x.RequestUri.AbsoluteUri); - - return new HttpResponseMessage(HttpStatusCode.OK) - { - Content = new ByteArrayContent(Encoding.UTF8.GetBytes("https://ux.nu/hoge")), - }; - }); + Content = new ByteArrayContent(Encoding.UTF8.GetBytes("https://ux.nu/hoge")), + }; + }); - Assert.Equal(new Uri("https://ux.nu/hoge"), - await shortUrl.ShortenUrlAsync(MyCommon.UrlConverter.Uxnu, new Uri("http://example.com/hogehoge"))); + Assert.Equal(new Uri("https://ux.nu/hoge"), + await shortUrl.ShortenUrlAsync(MyCommon.UrlConverter.Uxnu, new Uri("http://example.com/hogehoge"))); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } } } diff --git a/OpenTween.Tests/TabsDialogTest.cs b/OpenTween.Tests/TabsDialogTest.cs index 429c69026..c3306d20b 100644 --- a/OpenTween.Tests/TabsDialogTest.cs +++ b/OpenTween.Tests/TabsDialogTest.cs @@ -55,113 +55,103 @@ public TabsDialogTest() [Fact] public void OKButtonEnabledTest() { - using (var dialog = new TabsDialog(this.tabinfo)) - { - Assert.False(dialog.OK_Button.Enabled); + using var dialog = new TabsDialog(this.tabinfo); + Assert.False(dialog.OK_Button.Enabled); - dialog.TabList.SelectedIndex = 0; + dialog.TabList.SelectedIndex = 0; - Assert.True(dialog.OK_Button.Enabled); + Assert.True(dialog.OK_Button.Enabled); - dialog.TabList.SelectedIndex = -1; + dialog.TabList.SelectedIndex = -1; - Assert.False(dialog.OK_Button.Enabled); - } + Assert.False(dialog.OK_Button.Enabled); } [Fact] public void MultiSelectTest() { - using (var dialog = new TabsDialog(this.tabinfo)) - { - // MultiSelect = false (default) - var firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0]; - Assert.Null(firstItem.Tab); // 「(新規タブ)」 - Assert.Equal(SelectionMode.One, dialog.TabList.SelectionMode); - - dialog.MultiSelect = true; - firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0]; - Assert.NotNull(firstItem.Tab); - Assert.Equal(SelectionMode.MultiExtended, dialog.TabList.SelectionMode); - - dialog.MultiSelect = false; - firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0]; - Assert.Null(firstItem.Tab); - Assert.Equal(SelectionMode.One, dialog.TabList.SelectionMode); - } + using var dialog = new TabsDialog(this.tabinfo); + + // MultiSelect = false (default) + var firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0]; + Assert.Null(firstItem.Tab); // 「(新規タブ)」 + Assert.Equal(SelectionMode.One, dialog.TabList.SelectionMode); + + dialog.MultiSelect = true; + firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0]; + Assert.NotNull(firstItem.Tab); + Assert.Equal(SelectionMode.MultiExtended, dialog.TabList.SelectionMode); + + dialog.MultiSelect = false; + firstItem = (TabsDialog.TabListItem)dialog.TabList.Items[0]; + Assert.Null(firstItem.Tab); + Assert.Equal(SelectionMode.One, dialog.TabList.SelectionMode); } [Fact] public void DoubleClickTest() { - using (var dialog = new TabsDialog(this.tabinfo)) - { - dialog.TabList.SelectedIndex = -1; - TestUtils.FireEvent(dialog.TabList, "DoubleClick"); + using var dialog = new TabsDialog(this.tabinfo); - Assert.Equal(DialogResult.None, dialog.DialogResult); - Assert.False(dialog.IsDisposed); + dialog.TabList.SelectedIndex = -1; + TestUtils.FireEvent(dialog.TabList, "DoubleClick"); - dialog.TabList.SelectedIndex = 1; - TestUtils.FireEvent(dialog.TabList, "DoubleClick"); + Assert.Equal(DialogResult.None, dialog.DialogResult); + Assert.False(dialog.IsDisposed); - Assert.Equal(DialogResult.OK, dialog.DialogResult); - Assert.True(dialog.IsDisposed); - } + dialog.TabList.SelectedIndex = 1; + TestUtils.FireEvent(dialog.TabList, "DoubleClick"); + + Assert.Equal(DialogResult.OK, dialog.DialogResult); + Assert.True(dialog.IsDisposed); } [Fact] public void SelectableTabTest() { - using (var dialog = new TabsDialog(this.tabinfo)) - { - dialog.MultiSelect = false; + using var dialog = new TabsDialog(this.tabinfo); + dialog.MultiSelect = false; - var item = (TabsDialog.TabListItem)dialog.TabList.Items[0]; - Assert.Null(item.Tab); + var item = (TabsDialog.TabListItem)dialog.TabList.Items[0]; + Assert.Null(item.Tab); - item = (TabsDialog.TabListItem)dialog.TabList.Items[1]; - Assert.Equal(this.tabinfo.Tabs["Reply"], item.Tab); + item = (TabsDialog.TabListItem)dialog.TabList.Items[1]; + Assert.Equal(this.tabinfo.Tabs["Reply"], item.Tab); - item = (TabsDialog.TabListItem)dialog.TabList.Items[2]; - Assert.Equal(this.tabinfo.Tabs["MyTab1"], item.Tab); - } + item = (TabsDialog.TabListItem)dialog.TabList.Items[2]; + Assert.Equal(this.tabinfo.Tabs["MyTab1"], item.Tab); } [Fact] public void SelectedTabTest() { - using (var dialog = new TabsDialog(this.tabinfo)) - { - dialog.MultiSelect = false; + using var dialog = new TabsDialog(this.tabinfo); + dialog.MultiSelect = false; - dialog.TabList.SelectedIndex = 0; - Assert.Null(dialog.SelectedTab); + dialog.TabList.SelectedIndex = 0; + Assert.Null(dialog.SelectedTab); - dialog.TabList.SelectedIndex = 1; - Assert.Equal(this.tabinfo.Tabs["Reply"], dialog.SelectedTab); - } + dialog.TabList.SelectedIndex = 1; + Assert.Equal(this.tabinfo.Tabs["Reply"], dialog.SelectedTab); } [Fact] public void SelectedTabsTest() { - using (var dialog = new TabsDialog(this.tabinfo)) - { - dialog.MultiSelect = true; - - dialog.TabList.SelectedIndices.Clear(); - var selectedTabs = dialog.SelectedTabs; - Assert.Empty(selectedTabs); - - dialog.TabList.SelectedIndices.Add(0); - selectedTabs = dialog.SelectedTabs; - Assert.Equal(new[] { this.tabinfo.Tabs["Reply"] }, selectedTabs); - - dialog.TabList.SelectedIndices.Add(1); - selectedTabs = dialog.SelectedTabs; - Assert.Equal(new[] { this.tabinfo.Tabs["Reply"], this.tabinfo.Tabs["MyTab1"] }, selectedTabs); - } + using var dialog = new TabsDialog(this.tabinfo); + dialog.MultiSelect = true; + + dialog.TabList.SelectedIndices.Clear(); + var selectedTabs = dialog.SelectedTabs; + Assert.Empty(selectedTabs); + + dialog.TabList.SelectedIndices.Add(0); + selectedTabs = dialog.SelectedTabs; + Assert.Equal(new[] { this.tabinfo.Tabs["Reply"] }, selectedTabs); + + dialog.TabList.SelectedIndices.Add(1); + selectedTabs = dialog.SelectedTabs; + Assert.Equal(new[] { this.tabinfo.Tabs["Reply"], this.tabinfo.Tabs["MyTab1"] }, selectedTabs); } } } diff --git a/OpenTween.Tests/TestUtils.cs b/OpenTween.Tests/TestUtils.cs index 60eb7cfb5..1de865cc7 100644 --- a/OpenTween.Tests/TestUtils.cs +++ b/OpenTween.Tests/TestUtils.cs @@ -97,14 +97,12 @@ void Handler(object s, PropertyChangedEventArgs e) public static MemoryImage CreateDummyImage() { - using (var bitmap = new Bitmap(100, 100)) - using (var stream = new MemoryStream()) - { - bitmap.Save(stream, ImageFormat.Png); - stream.Position = 0; + using var bitmap = new Bitmap(100, 100); + using var stream = new MemoryStream(); + bitmap.Save(stream, ImageFormat.Png); + stream.Position = 0; - return MemoryImage.CopyFromStream(stream); - } + return MemoryImage.CopyFromStream(stream); } public static MemoryImageMediaItem CreateDummyMediaItem() diff --git a/OpenTween.Tests/Thumbnail/Services/FoursquareCheckinTest.cs b/OpenTween.Tests/Thumbnail/Services/FoursquareCheckinTest.cs index ae9edd984..6d8bb1f82 100644 --- a/OpenTween.Tests/Thumbnail/Services/FoursquareCheckinTest.cs +++ b/OpenTween.Tests/Thumbnail/Services/FoursquareCheckinTest.cs @@ -69,147 +69,139 @@ public void LegacyUrlPattern_Test() public async Task GetThumbnailInfoAsync_NewUrlTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); + using var http = new HttpClient(handler); + var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Get, x.Method); - Assert.Equal("https://api.foursquare.com/v2/checkins/resolve", - x.RequestUri.GetLeftPart(UriPartial.Path)); + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Get, x.Method); + Assert.Equal("https://api.foursquare.com/v2/checkins/resolve", + x.RequestUri.GetLeftPart(UriPartial.Path)); - var query = HttpUtility.ParseQueryString(x.RequestUri.Query); + var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - Assert.Equal("fake_client_id", query["client_id"]); - Assert.Equal("fake_client_secret", query["client_secret"]); - Assert.NotNull(query["v"]); - Assert.Equal("xxxxxxxx", query["shortId"]); + Assert.Equal("fake_client_id", query["client_id"]); + Assert.Equal("fake_client_secret", query["client_secret"]); + Assert.NotNull(query["v"]); + Assert.Equal("xxxxxxxx", query["shortId"]); - // リクエストに対するテストなのでレスポンスは適当に返す - return new HttpResponseMessage(HttpStatusCode.NotFound); - }); + // リクエストに対するテストなのでレスポンスは適当に返す + return new HttpResponseMessage(HttpStatusCode.NotFound); + }); - var post = new PostClass - { - PostGeo = null, - }; + var post = new PostClass + { + PostGeo = null, + }; - await service.GetThumbnailInfoAsync( - "https://www.swarmapp.com/c/xxxxxxxx", - post, - CancellationToken.None); + await service.GetThumbnailInfoAsync( + "https://www.swarmapp.com/c/xxxxxxxx", + post, + CancellationToken.None); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task GetThumbnailInfoAsync_LegacyUrlTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); + using var http = new HttpClient(handler); + var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Get, x.Method); - Assert.Equal("https://api.foursquare.com/v2/checkins/xxxxxxxx", - x.RequestUri.GetLeftPart(UriPartial.Path)); + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Get, x.Method); + Assert.Equal("https://api.foursquare.com/v2/checkins/xxxxxxxx", + x.RequestUri.GetLeftPart(UriPartial.Path)); - var query = HttpUtility.ParseQueryString(x.RequestUri.Query); + var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - Assert.Equal("fake_client_id", query["client_id"]); - Assert.Equal("fake_client_secret", query["client_secret"]); - Assert.NotNull(query["v"]); - Assert.Null(query["signature"]); + Assert.Equal("fake_client_id", query["client_id"]); + Assert.Equal("fake_client_secret", query["client_secret"]); + Assert.NotNull(query["v"]); + Assert.Null(query["signature"]); - // リクエストに対するテストなのでレスポンスは適当に返す - return new HttpResponseMessage(HttpStatusCode.NotFound); - }); + // リクエストに対するテストなのでレスポンスは適当に返す + return new HttpResponseMessage(HttpStatusCode.NotFound); + }); - var post = new PostClass - { - PostGeo = null, - }; + var post = new PostClass + { + PostGeo = null, + }; - await service.GetThumbnailInfoAsync( - "https://foursquare.com/hogehoge/checkin/xxxxxxxx", - post, - CancellationToken.None); + await service.GetThumbnailInfoAsync( + "https://foursquare.com/hogehoge/checkin/xxxxxxxx", + post, + CancellationToken.None); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task GetThumbnailInfoAsync_LegacyUrlWithSignatureTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) - { - var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); + using var http = new HttpClient(handler); + var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); - handler.Enqueue(x => - { - Assert.Equal(HttpMethod.Get, x.Method); - Assert.Equal("https://api.foursquare.com/v2/checkins/xxxxxxxx", - x.RequestUri.GetLeftPart(UriPartial.Path)); + handler.Enqueue(x => + { + Assert.Equal(HttpMethod.Get, x.Method); + Assert.Equal("https://api.foursquare.com/v2/checkins/xxxxxxxx", + x.RequestUri.GetLeftPart(UriPartial.Path)); - var query = HttpUtility.ParseQueryString(x.RequestUri.Query); + var query = HttpUtility.ParseQueryString(x.RequestUri.Query); - Assert.Equal("fake_client_id", query["client_id"]); - Assert.Equal("fake_client_secret", query["client_secret"]); - Assert.NotNull(query["v"]); - Assert.Equal("aaaaaaa", query["signature"]); + Assert.Equal("fake_client_id", query["client_id"]); + Assert.Equal("fake_client_secret", query["client_secret"]); + Assert.NotNull(query["v"]); + Assert.Equal("aaaaaaa", query["signature"]); - // リクエストに対するテストなのでレスポンスは適当に返す - return new HttpResponseMessage(HttpStatusCode.NotFound); - }); + // リクエストに対するテストなのでレスポンスは適当に返す + return new HttpResponseMessage(HttpStatusCode.NotFound); + }); - var post = new PostClass - { - PostGeo = null, - }; + var post = new PostClass + { + PostGeo = null, + }; - await service.GetThumbnailInfoAsync( - "https://foursquare.com/hogehoge/checkin/xxxxxxxx?s=aaaaaaa", - post, - CancellationToken.None); + await service.GetThumbnailInfoAsync( + "https://foursquare.com/hogehoge/checkin/xxxxxxxx?s=aaaaaaa", + post, + CancellationToken.None); - Assert.Equal(0, handler.QueueCount); - } + Assert.Equal(0, handler.QueueCount); } [Fact] public async Task GetThumbnailInfoAsync_GeoLocatedTweetTest() { var handler = new HttpMessageHandlerMock(); - using (var http = new HttpClient(handler)) + using var http = new HttpClient(handler); + var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); + + handler.Enqueue(x => { - var service = new FoursquareCheckin(http, ApiKey.Create("fake_client_id"), ApiKey.Create("fake_client_secret")); - - handler.Enqueue(x => - { - // このリクエストは実行されないはず - Assert.True(false); - return new HttpResponseMessage(HttpStatusCode.NotFound); - }); - - // 既にジオタグが付いているツイートに対しては何もしない - var post = new PostClass - { - PostGeo = new PostClass.StatusGeo(134.04693603515625, 34.35067978344854), - }; - - await service.GetThumbnailInfoAsync( - "https://www.swarmapp.com/c/xxxxxxxx", - post, - CancellationToken.None); - - Assert.Equal(1, handler.QueueCount); - } + // このリクエストは実行されないはず + Assert.True(false); + return new HttpResponseMessage(HttpStatusCode.NotFound); + }); + + // 既にジオタグが付いているツイートに対しては何もしない + var post = new PostClass + { + PostGeo = new PostClass.StatusGeo(134.04693603515625, 34.35067978344854), + }; + + await service.GetThumbnailInfoAsync( + "https://www.swarmapp.com/c/xxxxxxxx", + post, + CancellationToken.None); + + Assert.Equal(1, handler.QueueCount); } [Fact] diff --git a/OpenTween.Tests/ToolStripAPIGaugeTest.cs b/OpenTween.Tests/ToolStripAPIGaugeTest.cs index c93fd0495..8c13f5e6c 100644 --- a/OpenTween.Tests/ToolStripAPIGaugeTest.cs +++ b/OpenTween.Tests/ToolStripAPIGaugeTest.cs @@ -35,127 +35,122 @@ public class ToolStripAPIGaugeTest [Fact] public void ApiEndpointTest() { - using (var toolStrip = new TestToolStripAPIGauge()) - { - var now = DateTimeUtc.Now; - toolStrip.DateTimeNow = now; + using var toolStrip = new TestToolStripAPIGauge(); + var now = DateTimeUtc.Now; + toolStrip.DateTimeNow = now; - MyCommon.TwitterApiInfo.AccessLimit["endpoint1"] = new ApiLimit(15, 15, now + TimeSpan.FromMinutes(15)); - MyCommon.TwitterApiInfo.AccessLimit["endpoint2"] = new ApiLimit(180, 18, now + TimeSpan.FromMinutes(5)); + MyCommon.TwitterApiInfo.AccessLimit["endpoint1"] = new ApiLimit(15, 15, now + TimeSpan.FromMinutes(15)); + MyCommon.TwitterApiInfo.AccessLimit["endpoint2"] = new ApiLimit(180, 18, now + TimeSpan.FromMinutes(5)); - // toolStrip.ApiEndpoint の初期値は null + // toolStrip.ApiEndpoint の初期値は null - Assert.Null(toolStrip.ApiEndpoint); - Assert.Null(toolStrip.ApiLimit); + Assert.Null(toolStrip.ApiEndpoint); + Assert.Null(toolStrip.ApiLimit); - toolStrip.ApiEndpoint = "endpoint1"; + toolStrip.ApiEndpoint = "endpoint1"; - Assert.Equal("endpoint1", toolStrip.ApiEndpoint); - Assert.Equal(new ApiLimit(15, 15, now + TimeSpan.FromMinutes(15)), toolStrip.ApiLimit); + Assert.Equal("endpoint1", toolStrip.ApiEndpoint); + Assert.Equal(new ApiLimit(15, 15, now + TimeSpan.FromMinutes(15)), toolStrip.ApiLimit); - toolStrip.ApiEndpoint = "endpoint2"; + toolStrip.ApiEndpoint = "endpoint2"; - Assert.Equal("endpoint2", toolStrip.ApiEndpoint); - Assert.Equal(new ApiLimit(180, 18, now + TimeSpan.FromMinutes(5)), toolStrip.ApiLimit); + Assert.Equal("endpoint2", toolStrip.ApiEndpoint); + Assert.Equal(new ApiLimit(180, 18, now + TimeSpan.FromMinutes(5)), toolStrip.ApiLimit); - MyCommon.TwitterApiInfo.AccessLimit["endpoint2"] = new ApiLimit(180, 17, now + TimeSpan.FromMinutes(5)); - toolStrip.ApiEndpoint = "endpoint2"; + MyCommon.TwitterApiInfo.AccessLimit["endpoint2"] = new ApiLimit(180, 17, now + TimeSpan.FromMinutes(5)); + toolStrip.ApiEndpoint = "endpoint2"; - Assert.Equal("endpoint2", toolStrip.ApiEndpoint); - Assert.Equal(new ApiLimit(180, 17, now + TimeSpan.FromMinutes(5)), toolStrip.ApiLimit); + Assert.Equal("endpoint2", toolStrip.ApiEndpoint); + Assert.Equal(new ApiLimit(180, 17, now + TimeSpan.FromMinutes(5)), toolStrip.ApiLimit); - toolStrip.ApiEndpoint = "hoge"; + toolStrip.ApiEndpoint = "hoge"; - Assert.Equal("hoge", toolStrip.ApiEndpoint); - Assert.Null(toolStrip.ApiLimit); + Assert.Equal("hoge", toolStrip.ApiEndpoint); + Assert.Null(toolStrip.ApiLimit); - toolStrip.ApiEndpoint = ""; + toolStrip.ApiEndpoint = ""; - Assert.Null(toolStrip.ApiEndpoint); - Assert.Null(toolStrip.ApiLimit); + Assert.Null(toolStrip.ApiEndpoint); + Assert.Null(toolStrip.ApiLimit); - MyCommon.TwitterApiInfo.AccessLimit.Clear(); - } + MyCommon.TwitterApiInfo.AccessLimit.Clear(); } [Fact] public void GaugeHeightTest() { - using (var toolStrip = new ToolStripAPIGauge()) - { - toolStrip.AutoSize = false; - toolStrip.Size = new Size(100, 10); + using var toolStrip = new ToolStripAPIGauge(); + toolStrip.AutoSize = false; + toolStrip.Size = new Size(100, 10); - MyCommon.TwitterApiInfo.AccessLimit["endpoint"] = new ApiLimit(15, 15, DateTimeUtc.MaxValue); - toolStrip.ApiEndpoint = "endpoint"; + MyCommon.TwitterApiInfo.AccessLimit["endpoint"] = new ApiLimit(15, 15, DateTimeUtc.MaxValue); + toolStrip.ApiEndpoint = "endpoint"; - toolStrip.GaugeHeight = 5; + toolStrip.GaugeHeight = 5; - Assert.Equal(new Rectangle(0, 0, 100, 5), toolStrip.ApiGaugeBounds); - Assert.Equal(new Rectangle(0, 5, 100, 5), toolStrip.TimeGaugeBounds); + Assert.Equal(new Rectangle(0, 0, 100, 5), toolStrip.ApiGaugeBounds); + Assert.Equal(new Rectangle(0, 5, 100, 5), toolStrip.TimeGaugeBounds); - toolStrip.GaugeHeight = 3; + toolStrip.GaugeHeight = 3; - Assert.Equal(new Rectangle(0, 2, 100, 3), toolStrip.ApiGaugeBounds); - Assert.Equal(new Rectangle(0, 5, 100, 3), toolStrip.TimeGaugeBounds); + Assert.Equal(new Rectangle(0, 2, 100, 3), toolStrip.ApiGaugeBounds); + Assert.Equal(new Rectangle(0, 5, 100, 3), toolStrip.TimeGaugeBounds); - toolStrip.GaugeHeight = 0; + toolStrip.GaugeHeight = 0; - Assert.Equal(Rectangle.Empty, toolStrip.ApiGaugeBounds); - Assert.Equal(Rectangle.Empty, toolStrip.TimeGaugeBounds); + Assert.Equal(Rectangle.Empty, toolStrip.ApiGaugeBounds); + Assert.Equal(Rectangle.Empty, toolStrip.TimeGaugeBounds); - MyCommon.TwitterApiInfo.AccessLimit.Clear(); - } + MyCommon.TwitterApiInfo.AccessLimit.Clear(); } [Fact] public void TextTest() { - using (var toolStrip = new ToolStripAPIGauge()) - { - MyCommon.TwitterApiInfo.AccessLimit["/statuses/home_timeline"] = new ApiLimit(15, 15, DateTimeUtc.Now + TimeSpan.FromMinutes(15)); - MyCommon.TwitterApiInfo.AccessLimit["/statuses/user_timeline"] = new ApiLimit(180, 18, DateTimeUtc.Now + TimeSpan.FromMinutes(-2)); - MyCommon.TwitterApiInfo.AccessLimit["/search/tweets"] = new ApiLimit(180, 90, DateTimeUtc.Now + TimeSpan.FromMinutes(5)); + using var toolStrip = new ToolStripAPIGauge(); - // toolStrip.ApiEndpoint の初期値は null + MyCommon.TwitterApiInfo.AccessLimit["/statuses/home_timeline"] = new ApiLimit(15, 15, DateTimeUtc.Now + TimeSpan.FromMinutes(15)); + MyCommon.TwitterApiInfo.AccessLimit["/statuses/user_timeline"] = new ApiLimit(180, 18, DateTimeUtc.Now + TimeSpan.FromMinutes(-2)); + MyCommon.TwitterApiInfo.AccessLimit["/search/tweets"] = new ApiLimit(180, 90, DateTimeUtc.Now + TimeSpan.FromMinutes(5)); - Assert.Equal("API ???/???", toolStrip.Text); - Assert.Equal("API rest unknown ???/???" + Environment.NewLine + "(reset after ??? minutes)", toolStrip.ToolTipText); + // toolStrip.ApiEndpoint の初期値は null - toolStrip.ApiEndpoint = "/search/tweets"; + Assert.Equal("API ???/???", toolStrip.Text); + Assert.Equal("API rest unknown ???/???" + Environment.NewLine + "(reset after ??? minutes)", toolStrip.ToolTipText); - Assert.Equal("API 90/180", toolStrip.Text); - Assert.Equal("API rest /search/tweets 90/180" + Environment.NewLine + "(reset after 5 minutes)", toolStrip.ToolTipText); + toolStrip.ApiEndpoint = "/search/tweets"; - toolStrip.ApiEndpoint = "/statuses/user_timeline"; + Assert.Equal("API 90/180", toolStrip.Text); + Assert.Equal("API rest /search/tweets 90/180" + Environment.NewLine + "(reset after 5 minutes)", toolStrip.ToolTipText); - Assert.Equal("API ???/???", toolStrip.Text); - Assert.Equal("API rest /statuses/user_timeline ???/???" + Environment.NewLine + "(reset after ??? minutes)", toolStrip.ToolTipText); + toolStrip.ApiEndpoint = "/statuses/user_timeline"; - MyCommon.TwitterApiInfo.AccessLimit["/statuses/user_timeline"] = new ApiLimit(180, 180, DateTimeUtc.Now + TimeSpan.FromMinutes(15)); - toolStrip.ApiEndpoint = "/statuses/user_timeline"; + Assert.Equal("API ???/???", toolStrip.Text); + Assert.Equal("API rest /statuses/user_timeline ???/???" + Environment.NewLine + "(reset after ??? minutes)", toolStrip.ToolTipText); - Assert.Equal("API 180/180", toolStrip.Text); - Assert.Equal("API rest /statuses/user_timeline 180/180" + Environment.NewLine + "(reset after 15 minutes)", toolStrip.ToolTipText); + MyCommon.TwitterApiInfo.AccessLimit["/statuses/user_timeline"] = new ApiLimit(180, 180, DateTimeUtc.Now + TimeSpan.FromMinutes(15)); + toolStrip.ApiEndpoint = "/statuses/user_timeline"; - MyCommon.TwitterApiInfo.AccessLimit["/statuses/user_timeline"] = new ApiLimit(180, 179, DateTimeUtc.Now + TimeSpan.FromMinutes(15)); - toolStrip.ApiEndpoint = "/statuses/user_timeline"; + Assert.Equal("API 180/180", toolStrip.Text); + Assert.Equal("API rest /statuses/user_timeline 180/180" + Environment.NewLine + "(reset after 15 minutes)", toolStrip.ToolTipText); - Assert.Equal("API 179/180", toolStrip.Text); - Assert.Equal("API rest /statuses/user_timeline 179/180" + Environment.NewLine + "(reset after 15 minutes)", toolStrip.ToolTipText); + MyCommon.TwitterApiInfo.AccessLimit["/statuses/user_timeline"] = new ApiLimit(180, 179, DateTimeUtc.Now + TimeSpan.FromMinutes(15)); + toolStrip.ApiEndpoint = "/statuses/user_timeline"; - toolStrip.ApiEndpoint = "hoge"; + Assert.Equal("API 179/180", toolStrip.Text); + Assert.Equal("API rest /statuses/user_timeline 179/180" + Environment.NewLine + "(reset after 15 minutes)", toolStrip.ToolTipText); - Assert.Equal("API ???/???", toolStrip.Text); - Assert.Equal("API rest hoge ???/???" + Environment.NewLine + "(reset after ??? minutes)", toolStrip.ToolTipText); + toolStrip.ApiEndpoint = "hoge"; - toolStrip.ApiEndpoint = ""; + Assert.Equal("API ???/???", toolStrip.Text); + Assert.Equal("API rest hoge ???/???" + Environment.NewLine + "(reset after ??? minutes)", toolStrip.ToolTipText); - Assert.Equal("API ???/???", toolStrip.Text); - Assert.Equal("API rest unknown ???/???" + Environment.NewLine + "(reset after ??? minutes)", toolStrip.ToolTipText); + toolStrip.ApiEndpoint = ""; - MyCommon.TwitterApiInfo.AccessLimit.Clear(); - } + Assert.Equal("API ???/???", toolStrip.Text); + Assert.Equal("API rest unknown ???/???" + Environment.NewLine + "(reset after ??? minutes)", toolStrip.ToolTipText); + + MyCommon.TwitterApiInfo.AccessLimit.Clear(); } private class TestToolStripAPIGauge : ToolStripAPIGauge @@ -175,33 +170,32 @@ protected override void UpdateRemainMinutes() [Fact] public void GaugeBoundsTest() { - using (var toolStrip = new TestToolStripAPIGauge()) - { - var now = DateTimeUtc.Now; - toolStrip.DateTimeNow = now; + using var toolStrip = new TestToolStripAPIGauge(); - toolStrip.AutoSize = false; - toolStrip.Size = new Size(100, 10); - toolStrip.GaugeHeight = 5; + var now = DateTimeUtc.Now; + toolStrip.DateTimeNow = now; - // toolStrip.ApiEndpoint の初期値は null + toolStrip.AutoSize = false; + toolStrip.Size = new Size(100, 10); + toolStrip.GaugeHeight = 5; - Assert.Equal(Rectangle.Empty, toolStrip.ApiGaugeBounds); - Assert.Equal(Rectangle.Empty, toolStrip.TimeGaugeBounds); + // toolStrip.ApiEndpoint の初期値は null - MyCommon.TwitterApiInfo.AccessLimit["endpoint"] = new ApiLimit(150, 60, now + TimeSpan.FromMinutes(3)); - toolStrip.ApiEndpoint = "endpoint"; + Assert.Equal(Rectangle.Empty, toolStrip.ApiGaugeBounds); + Assert.Equal(Rectangle.Empty, toolStrip.TimeGaugeBounds); - Assert.Equal(new Rectangle(0, 0, 40, 5), toolStrip.ApiGaugeBounds); // 40% (60/150) - Assert.Equal(new Rectangle(0, 5, 20, 5), toolStrip.TimeGaugeBounds); // 20% (3/15) + MyCommon.TwitterApiInfo.AccessLimit["endpoint"] = new ApiLimit(150, 60, now + TimeSpan.FromMinutes(3)); + toolStrip.ApiEndpoint = "endpoint"; - toolStrip.ApiEndpoint = ""; + Assert.Equal(new Rectangle(0, 0, 40, 5), toolStrip.ApiGaugeBounds); // 40% (60/150) + Assert.Equal(new Rectangle(0, 5, 20, 5), toolStrip.TimeGaugeBounds); // 20% (3/15) - Assert.Equal(Rectangle.Empty, toolStrip.ApiGaugeBounds); - Assert.Equal(Rectangle.Empty, toolStrip.TimeGaugeBounds); + toolStrip.ApiEndpoint = ""; - MyCommon.TwitterApiInfo.AccessLimit.Clear(); - } + Assert.Equal(Rectangle.Empty, toolStrip.ApiGaugeBounds); + Assert.Equal(Rectangle.Empty, toolStrip.TimeGaugeBounds); + + MyCommon.TwitterApiInfo.AccessLimit.Clear(); } [Fact] diff --git a/OpenTween.Tests/TweenMainTest.cs b/OpenTween.Tests/TweenMainTest.cs index de1d42699..275074c1e 100644 --- a/OpenTween.Tests/TweenMainTest.cs +++ b/OpenTween.Tests/TweenMainTest.cs @@ -37,50 +37,42 @@ public class TweenMainTest public void GetUrlFromDataObject_XMozUrlTest() { var dataBytes = Encoding.Unicode.GetBytes("https://twitter.com/\nTwitter\0"); - using (var memstream = new MemoryStream(dataBytes)) - { - var data = new DataObject("text/x-moz-url", memstream); + using var memstream = new MemoryStream(dataBytes); + var data = new DataObject("text/x-moz-url", memstream); - var expected = ("https://twitter.com/", "Twitter"); - Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data)); - } + var expected = ("https://twitter.com/", "Twitter"); + Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data)); } [Fact] public void GetUrlFromDataObject_IESiteModeToUrlTest() { var dataBytes = Encoding.Unicode.GetBytes("https://twitter.com/\0Twitter\0"); - using (var memstream = new MemoryStream(dataBytes)) - { - var data = new DataObject("IESiteModeToUrl", memstream); + using var memstream = new MemoryStream(dataBytes); + var data = new DataObject("IESiteModeToUrl", memstream); - var expected = ("https://twitter.com/", "Twitter"); - Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data)); - } + var expected = ("https://twitter.com/", "Twitter"); + Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data)); } [Fact] public void GetUrlFromDataObject_UniformResourceLocatorWTest() { var dataBytes = Encoding.Unicode.GetBytes("https://twitter.com/\0"); - using (var memstream = new MemoryStream(dataBytes)) - { - var data = new DataObject("UniformResourceLocatorW", memstream); + using var memstream = new MemoryStream(dataBytes); + var data = new DataObject("UniformResourceLocatorW", memstream); - var expected = ("https://twitter.com/", (string?)null); - Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data)); - } + var expected = ("https://twitter.com/", (string?)null); + Assert.Equal(expected, TweenMain.GetUrlFromDataObject(data)); } [Fact] public void GetUrlFromDataObject_UnknownFormatTest() { - using (var memstream = new MemoryStream(Array.Empty())) - { - var data = new DataObject("application/x-hogehoge", memstream); + using var memstream = new MemoryStream(Array.Empty()); + var data = new DataObject("application/x-hogehoge", memstream); - Assert.Throws(() => TweenMain.GetUrlFromDataObject(data)); - } + Assert.Throws(() => TweenMain.GetUrlFromDataObject(data)); } [Fact] diff --git a/OpenTween.Tests/TweetThumbnailTest.cs b/OpenTween.Tests/TweetThumbnailTest.cs index 2e14a01f5..183cfc51f 100644 --- a/OpenTween.Tests/TweetThumbnailTest.cs +++ b/OpenTween.Tests/TweetThumbnailTest.cs @@ -106,19 +106,18 @@ private void MyCommonSetup() [Fact] public void CreatePictureBoxTest() { - using (var thumbBox = new TweetThumbnail()) - { - var method = typeof(TweetThumbnail).GetMethod("CreatePictureBox", BindingFlags.Instance | BindingFlags.NonPublic); - var picbox = method.Invoke(thumbBox, new[] { "pictureBox1" }) as PictureBox; + using var thumbBox = new TweetThumbnail(); - Assert.NotNull(picbox); - Assert.Equal("pictureBox1", picbox!.Name); - Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); - Assert.False(picbox.WaitOnLoad); - Assert.Equal(DockStyle.Fill, picbox.Dock); + var method = typeof(TweetThumbnail).GetMethod("CreatePictureBox", BindingFlags.Instance | BindingFlags.NonPublic); + var picbox = method.Invoke(thumbBox, new[] { "pictureBox1" }) as PictureBox; - picbox.Dispose(); - } + Assert.NotNull(picbox); + Assert.Equal("pictureBox1", picbox!.Name); + Assert.Equal(PictureBoxSizeMode.Zoom, picbox.SizeMode); + Assert.False(picbox.WaitOnLoad); + Assert.Equal(DockStyle.Fill, picbox.Dock); + + picbox.Dispose(); } [Fact] @@ -133,17 +132,16 @@ public async Task CancelAsyncTest() }, }; - using (var thumbbox = new TweetThumbnail()) - using (var tokenSource = new CancellationTokenSource()) - { - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var task = thumbbox.ShowThumbnailAsync(post, tokenSource.Token); + using var thumbbox = new TweetThumbnail(); + using var tokenSource = new CancellationTokenSource(); - tokenSource.Cancel(); + SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); + var task = thumbbox.ShowThumbnailAsync(post, tokenSource.Token); - await Assert.ThrowsAnyAsync(async () => await task); - Assert.True(task.IsCanceled); - } + tokenSource.Cancel(); + + await Assert.ThrowsAnyAsync(async () => await task); + Assert.True(task.IsCanceled); } [Theory] @@ -152,29 +150,28 @@ public async Task CancelAsyncTest() [InlineData(2)] public void SetThumbnailCountTest(int count) { - using (var thumbbox = new TweetThumbnail()) - { - var method = typeof(TweetThumbnail).GetMethod("SetThumbnailCount", BindingFlags.Instance | BindingFlags.NonPublic); - method.Invoke(thumbbox, new[] { (object)count }); + using var thumbbox = new TweetThumbnail(); - Assert.Equal(count, thumbbox.PictureBox.Count); + var method = typeof(TweetThumbnail).GetMethod("SetThumbnailCount", BindingFlags.Instance | BindingFlags.NonPublic); + method.Invoke(thumbbox, new[] { (object)count }); - var num = 0; - foreach (var picbox in thumbbox.PictureBox) - { - Assert.Equal("pictureBox" + num, picbox.Name); - num++; - } + Assert.Equal(count, thumbbox.PictureBox.Count); + + var num = 0; + foreach (var picbox in thumbbox.PictureBox) + { + Assert.Equal("pictureBox" + num, picbox.Name); + num++; + } - Assert.Equal(thumbbox.PictureBox, thumbbox.panelPictureBox.Controls.Cast()); + Assert.Equal(thumbbox.PictureBox, thumbbox.panelPictureBox.Controls.Cast()); - Assert.Equal(0, thumbbox.scrollBar.Minimum); + Assert.Equal(0, thumbbox.scrollBar.Minimum); - if (count == 0) - Assert.Equal(0, thumbbox.scrollBar.Maximum); - else - Assert.Equal(count - 1, thumbbox.scrollBar.Maximum); - } + if (count == 0) + Assert.Equal(0, thumbbox.scrollBar.Maximum); + else + Assert.Equal(count - 1, thumbbox.scrollBar.Maximum); } [Fact] @@ -189,25 +186,24 @@ public async Task ShowThumbnailAsyncTest() }, }; - using (var thumbbox = new TweetThumbnail()) - { - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - await thumbbox.ShowThumbnailAsync(post); + using var thumbbox = new TweetThumbnail(); - Assert.Equal(0, thumbbox.scrollBar.Maximum); - Assert.False(thumbbox.scrollBar.Enabled); + SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); + await thumbbox.ShowThumbnailAsync(post); - Assert.Single(thumbbox.PictureBox); - Assert.NotNull(thumbbox.PictureBox[0].Image); + Assert.Equal(0, thumbbox.scrollBar.Maximum); + Assert.False(thumbbox.scrollBar.Enabled); - Assert.IsAssignableFrom(thumbbox.PictureBox[0].Tag); - var thumbinfo = (ThumbnailInfo)thumbbox.PictureBox[0].Tag; + Assert.Single(thumbbox.PictureBox); + Assert.NotNull(thumbbox.PictureBox[0].Image); - Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl); - Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl); + Assert.IsAssignableFrom(thumbbox.PictureBox[0].Tag); + var thumbinfo = (ThumbnailInfo)thumbbox.PictureBox[0].Tag; - Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[0])); - } + Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl); + Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl); + + Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[0])); } [Fact] @@ -223,72 +219,70 @@ public async Task ShowThumbnailAsyncTest2() }, }; - using (var thumbbox = new TweetThumbnail()) - { - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - await thumbbox.ShowThumbnailAsync(post); + using var thumbbox = new TweetThumbnail(); - Assert.Equal(1, thumbbox.scrollBar.Maximum); - Assert.True(thumbbox.scrollBar.Enabled); + SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); + await thumbbox.ShowThumbnailAsync(post); - Assert.Equal(2, thumbbox.PictureBox.Count); - Assert.NotNull(thumbbox.PictureBox[0].Image); - Assert.NotNull(thumbbox.PictureBox[1].Image); + Assert.Equal(1, thumbbox.scrollBar.Maximum); + Assert.True(thumbbox.scrollBar.Enabled); - Assert.IsAssignableFrom(thumbbox.PictureBox[0].Tag); - var thumbinfo = (ThumbnailInfo)thumbbox.PictureBox[0].Tag; + Assert.Equal(2, thumbbox.PictureBox.Count); + Assert.NotNull(thumbbox.PictureBox[0].Image); + Assert.NotNull(thumbbox.PictureBox[1].Image); - Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl); - Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl); + Assert.IsAssignableFrom(thumbbox.PictureBox[0].Tag); + var thumbinfo = (ThumbnailInfo)thumbbox.PictureBox[0].Tag; - Assert.IsAssignableFrom(thumbbox.PictureBox[1].Tag); - thumbinfo = (ThumbnailInfo)thumbbox.PictureBox[1].Tag; + Assert.Equal("http://foo.example.com/abcd", thumbinfo.MediaPageUrl); + Assert.Equal("http://img.example.com/abcd.png", thumbinfo.ThumbnailImageUrl); - Assert.Equal("http://bar.example.com/efgh", thumbinfo.MediaPageUrl); - Assert.Equal("http://img.example.com/efgh.png", thumbinfo.ThumbnailImageUrl); + Assert.IsAssignableFrom(thumbbox.PictureBox[1].Tag); + thumbinfo = (ThumbnailInfo)thumbbox.PictureBox[1].Tag; - Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[0])); - Assert.Equal("efgh", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[1])); - } + Assert.Equal("http://bar.example.com/efgh", thumbinfo.MediaPageUrl); + Assert.Equal("http://img.example.com/efgh.png", thumbinfo.ThumbnailImageUrl); + + Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[0])); + Assert.Equal("efgh", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[1])); } [Fact] public async Task ThumbnailLoadingEventTest() { - using (var thumbbox = new TweetThumbnail()) - { - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); + using var thumbbox = new TweetThumbnail(); + + SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var post = new PostClass + var post = new PostClass + { + TextFromApi = "てすと", + Media = new List { - TextFromApi = "てすと", - Media = new List - { - }, - }; - await TestUtils.NotRaisesAsync( - x => thumbbox.ThumbnailLoading += x, - x => thumbbox.ThumbnailLoading -= x, - () => thumbbox.ShowThumbnailAsync(post) - ); + }, + }; + await TestUtils.NotRaisesAsync( + x => thumbbox.ThumbnailLoading += x, + x => thumbbox.ThumbnailLoading -= x, + () => thumbbox.ShowThumbnailAsync(post) + ); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); + SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var post2 = new PostClass - { - TextFromApi = "てすと http://foo.example.com/abcd", - Media = new List + var post2 = new PostClass + { + TextFromApi = "てすと http://foo.example.com/abcd", + Media = new List { new MediaInfo("http://foo.example.com/abcd"), }, - }; + }; - await Assert.RaisesAsync( - x => thumbbox.ThumbnailLoading += x, - x => thumbbox.ThumbnailLoading -= x, - () => thumbbox.ShowThumbnailAsync(post2) - ); - } + await Assert.RaisesAsync( + x => thumbbox.ThumbnailLoading += x, + x => thumbbox.ThumbnailLoading -= x, + () => thumbbox.ShowThumbnailAsync(post2) + ); } [Fact] @@ -304,36 +298,35 @@ public async Task ScrollTest() }, }; - using (var thumbbox = new TweetThumbnail()) - { - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - await thumbbox.ShowThumbnailAsync(post); + using var thumbbox = new TweetThumbnail(); - Assert.Equal(0, thumbbox.scrollBar.Minimum); - Assert.Equal(1, thumbbox.scrollBar.Maximum); + SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); + await thumbbox.ShowThumbnailAsync(post); - thumbbox.scrollBar.Value = 0; + Assert.Equal(0, thumbbox.scrollBar.Minimum); + Assert.Equal(1, thumbbox.scrollBar.Maximum); - thumbbox.ScrollDown(); - Assert.Equal(1, thumbbox.scrollBar.Value); - Assert.False(thumbbox.PictureBox[0].Visible); - Assert.True(thumbbox.PictureBox[1].Visible); + thumbbox.scrollBar.Value = 0; - thumbbox.ScrollDown(); - Assert.Equal(1, thumbbox.scrollBar.Value); - Assert.False(thumbbox.PictureBox[0].Visible); - Assert.True(thumbbox.PictureBox[1].Visible); + thumbbox.ScrollDown(); + Assert.Equal(1, thumbbox.scrollBar.Value); + Assert.False(thumbbox.PictureBox[0].Visible); + Assert.True(thumbbox.PictureBox[1].Visible); - thumbbox.ScrollUp(); - Assert.Equal(0, thumbbox.scrollBar.Value); - Assert.True(thumbbox.PictureBox[0].Visible); - Assert.False(thumbbox.PictureBox[1].Visible); + thumbbox.ScrollDown(); + Assert.Equal(1, thumbbox.scrollBar.Value); + Assert.False(thumbbox.PictureBox[0].Visible); + Assert.True(thumbbox.PictureBox[1].Visible); - thumbbox.ScrollUp(); - Assert.Equal(0, thumbbox.scrollBar.Value); - Assert.True(thumbbox.PictureBox[0].Visible); - Assert.False(thumbbox.PictureBox[1].Visible); - } + thumbbox.ScrollUp(); + Assert.Equal(0, thumbbox.scrollBar.Value); + Assert.True(thumbbox.PictureBox[0].Visible); + Assert.False(thumbbox.PictureBox[1].Visible); + + thumbbox.ScrollUp(); + Assert.Equal(0, thumbbox.scrollBar.Value); + Assert.True(thumbbox.PictureBox[0].Visible); + Assert.False(thumbbox.PictureBox[1].Visible); } } } From 31c1a973c9f1ce2dd162671ce60cbdf018c65d5b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:11:31 +0900 Subject: [PATCH 135/402] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AA=E4=BB=A3?= =?UTF-8?q?=E5=85=A5=E3=82=92=E5=89=8A=E9=99=A4=20(IDE0059)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/TweetExtractor.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/OpenTween/TweetExtractor.cs b/OpenTween/TweetExtractor.cs index 9b1dfd946..62cae27cc 100644 --- a/OpenTween/TweetExtractor.cs +++ b/OpenTween/TweetExtractor.cs @@ -62,13 +62,11 @@ public static IEnumerable ExtractUrlEntities(string text) if (Regex.IsMatch(before, Twitter.UrlInvalidWithoutProtocolPrecedingChars)) continue; - string? lasturl = null; - var last_url_invalid_match = false; var domainMatches = Regex.Matches(domain, Twitter.UrlValidAsciiDomain, RegexOptions.IgnoreCase).Cast(); foreach (var mm in domainMatches) { - lasturl = mm.Value; + var lasturl = mm.Value; last_url_invalid_match = Regex.IsMatch(lasturl, Twitter.UrlInvalidShortDomain, RegexOptions.IgnoreCase); if (!last_url_invalid_match) { From 6e954fd6ef85d06d6690f306a91417cef6a8604e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:08:24 +0900 Subject: [PATCH 136/402] =?UTF-8?q?=E3=83=95=E3=82=A3=E3=83=BC=E3=83=AB?= =?UTF-8?q?=E3=83=89=E3=82=92readonly=E3=81=AB=E3=81=99=E3=82=8B=20(IDE004?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/PostClassTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index 26da96d27..e75575fb1 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -34,7 +34,7 @@ public class PostClassTest { private class PostClassGroup { - private Dictionary testCases; + private readonly Dictionary testCases; public PostClassGroup(params TestPostClass[] postClasses) { @@ -67,7 +67,7 @@ protected override PostClass RetweetSource } } - private PostClassGroup postGroup; + private readonly PostClassGroup postGroup; public PostClassTest() { From 0980aeb3d175e7ffa548a5b63d82b488bc8b5eb0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:03:40 +0900 Subject: [PATCH 137/402] =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB?= =?UTF-8?q?=E9=96=A2=E6=95=B0=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= =?UTF-8?q?=20(IDE0039)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/AsyncTimerTest.cs | 8 ++-- OpenTween.Tests/DebounceTimerTest.cs | 56 +++++++++++++++++----------- OpenTween.Tests/ThrottleTimerTest.cs | 24 +++++++----- 3 files changed, 55 insertions(+), 33 deletions(-) diff --git a/OpenTween.Tests/AsyncTimerTest.cs b/OpenTween.Tests/AsyncTimerTest.cs index 1c7d130a2..c3f1a785a 100644 --- a/OpenTween.Tests/AsyncTimerTest.cs +++ b/OpenTween.Tests/AsyncTimerTest.cs @@ -69,11 +69,13 @@ public void Change_PropertiesTest() public async Task UnhandledException_Test() { var tcs = new TaskCompletionSource(); - EventHandler handler = (_, ev) => tcs.TrySetResult(ev.Exception); + + void Handler(object sender, ThreadExceptionEventArgs ev) + => tcs.TrySetResult(ev.Exception); try { - AsyncTimer.UnhandledException += handler; + AsyncTimer.UnhandledException += Handler; using var timer = new AsyncTimer(() => { @@ -88,7 +90,7 @@ public async Task UnhandledException_Test() } finally { - AsyncTimer.UnhandledException -= handler; + AsyncTimer.UnhandledException -= Handler; } } } diff --git a/OpenTween.Tests/DebounceTimerTest.cs b/OpenTween.Tests/DebounceTimerTest.cs index a9fdd50de..aadda5b2c 100644 --- a/OpenTween.Tests/DebounceTimerTest.cs +++ b/OpenTween.Tests/DebounceTimerTest.cs @@ -49,15 +49,17 @@ public async Task Callback_Debounce_Trailing_Test() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.MaxValue; - using var debouncing = new TestDebounceTimer(callback, interval, leading: false, trailing: true); + using var debouncing = new TestDebounceTimer(Callback, interval, leading: false, trailing: true); var mockTimer = debouncing.MockTimer; Assert.Equal(0, count); @@ -104,15 +106,17 @@ public async Task Callback_Debounce_Trailing_CallOnceTest() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.MaxValue; - using var debouncing = new TestDebounceTimer(callback, interval, leading: false, trailing: true); + using var debouncing = new TestDebounceTimer(Callback, interval, leading: false, trailing: true); var mockTimer = debouncing.MockTimer; Assert.Equal(0, count); @@ -142,15 +146,17 @@ public async Task Callback_Debounce_Trailing_ResumeTest() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.MaxValue; - using var debouncing = new TestDebounceTimer(callback, interval, leading: false, trailing: true); + using var debouncing = new TestDebounceTimer(Callback, interval, leading: false, trailing: true); var mockTimer = debouncing.MockTimer; Assert.Equal(0, count); @@ -196,15 +202,17 @@ public async Task Callback_Debounce_LeadingAndTrailing_Test() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.MaxValue; - using var debouncing = new TestDebounceTimer(callback, interval, leading: true, trailing: true); + using var debouncing = new TestDebounceTimer(Callback, interval, leading: true, trailing: true); var mockTimer = debouncing.MockTimer; Assert.Equal(0, count); @@ -251,15 +259,17 @@ public async Task Callback_Debounce_LeadingAndTrailing_CallOnceTest() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.MaxValue; - using var debouncing = new TestDebounceTimer(callback, interval, leading: true, trailing: true); + using var debouncing = new TestDebounceTimer(Callback, interval, leading: true, trailing: true); var mockTimer = debouncing.MockTimer; Assert.Equal(0, count); @@ -289,15 +299,17 @@ public async Task Callback_Debounce_LeadingAndTrailing_ResumeTest() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.MaxValue; - using var debouncing = new TestDebounceTimer(callback, interval, leading: true, trailing: true); + using var debouncing = new TestDebounceTimer(Callback, interval, leading: true, trailing: true); var mockTimer = debouncing.MockTimer; Assert.Equal(0, count); @@ -360,15 +372,17 @@ public async Task Callback_Debounce_SystemClockChangedTest() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 1, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.MaxValue; - using var debouncing = new TestDebounceTimer(callback, interval, leading: false, trailing: true); + using var debouncing = new TestDebounceTimer(Callback, interval, leading: false, trailing: true); var mockTimer = debouncing.MockTimer; Assert.Equal(0, count); diff --git a/OpenTween.Tests/ThrottleTimerTest.cs b/OpenTween.Tests/ThrottleTimerTest.cs index 0158141ed..280d8f633 100644 --- a/OpenTween.Tests/ThrottleTimerTest.cs +++ b/OpenTween.Tests/ThrottleTimerTest.cs @@ -50,15 +50,17 @@ public async Task Callback_ThrottleTest() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.FromMinutes(2); - using var throttling = new TestThrottleTimer(callback, interval); + using var throttling = new TestThrottleTimer(Callback, interval); var mockTimer = throttling.MockTimer; Assert.Equal(0, count); @@ -105,15 +107,17 @@ public async Task Callback_CallOnceTest() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.FromMinutes(2); - using var throttling = new TestThrottleTimer(callback, interval); + using var throttling = new TestThrottleTimer(Callback, interval); var mockTimer = throttling.MockTimer; Assert.Equal(0, count); @@ -143,15 +147,17 @@ public async Task Callback_ResumeTest() using (TestUtils.FreezeTime(new DateTimeUtc(2022, 1, 1, 0, 0, 0))) { var count = 0; - Func callback = () => + + Task Callback() { count++; TestUtils.DriftTime(TimeSpan.FromSeconds(10)); return Task.CompletedTask; - }; + } + var interval = TimeSpan.FromMinutes(2); var maxWait = TimeSpan.FromMinutes(2); - using var throttling = new TestThrottleTimer(callback, interval); + using var throttling = new TestThrottleTimer(Callback, interval); var mockTimer = throttling.MockTimer; Assert.Equal(0, count); From 682b34287064c7e77b286b244ad8a4af19e0913f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:00:12 +0900 Subject: [PATCH 138/402] =?UTF-8?q?=E5=8C=BF=E5=90=8D=E5=9E=8B=E3=81=AE?= =?UTF-8?q?=E3=83=A1=E3=83=B3=E3=83=90=E3=83=BC=E5=90=8D=E3=82=92=E7=B0=A1?= =?UTF-8?q?=E7=B4=A0=E5=8C=96=20(IDE0037)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/RegexAsync.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenTween/RegexAsync.cs b/OpenTween/RegexAsync.cs index f21eca0a1..aeae95d2d 100644 --- a/OpenTween/RegexAsync.cs +++ b/OpenTween/RegexAsync.cs @@ -41,7 +41,7 @@ public static async Task ReplaceAsync(this Regex regex, string input, Fu .GroupBy(x => x.Value) // ToDictionaryする際に key が重複しないようにする .Select(async x => new { - Key = x.Key, + x.Key, Value = await evaluator(x.First()).ConfigureAwait(false), }); From e4e8053b070b4f64045f71cf24f76be9175fd9b4 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 17:58:53 +0900 Subject: [PATCH 139/402] =?UTF-8?q?out=20var=20=E3=81=AB=E3=82=88=E3=82=8B?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=83=A9=E3=82=A4=E3=83=B3=E5=A4=89=E6=95=B0?= =?UTF-8?q?=E5=AE=A3=E8=A8=80=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= =?UTF-8?q?(IDE0018)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ShortUrl.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenTween/ShortUrl.cs b/OpenTween/ShortUrl.cs index 996d0e28e..b6dab0e06 100644 --- a/OpenTween/ShortUrl.cs +++ b/OpenTween/ShortUrl.cs @@ -205,8 +205,7 @@ public async Task ExpandUrlAsync(Uri uri, int redirectLimit) if (!ShortUrlHosts.Contains(uri.Host) && !this.IsIrregularShortUrl(uri)) return uri; - Uri? expanded; - if (this.urlCache.TryGetValue(uri, out expanded)) + if (this.urlCache.TryGetValue(uri, out var expanded)) return expanded; if (this.urlCache.Count > this.PurgeCount) From b13de1b258b7d381b72fed4998a6d692a4bf4a82 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:45:16 +0900 Subject: [PATCH 140/402] =?UTF-8?q?var=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99?= =?UTF-8?q?=E3=82=8B=20(IDE0007)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/MyCommon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 9407cc6a3..3c7f5ba49 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -1017,7 +1017,7 @@ public static ProcessStartInfo CreateBrowserProcessStartInfo(string? browserPath }; } - int quoteEnd = -1; + var quoteEnd = -1; if (browserPathWithArgs.StartsWith("\"", StringComparison.Ordinal)) quoteEnd = browserPathWithArgs.IndexOf("\"", 1, StringComparison.Ordinal); From eec1e0786ce9171d0c7e5fd4fb3bc7579b652035 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 18:43:49 +0900 Subject: [PATCH 141/402] =?UTF-8?q?enum=E3=81=AE=E3=83=89=E3=82=AD?= =?UTF-8?q?=E3=83=A5=E3=83=A1=E3=83=B3=E3=83=88=E3=82=B3=E3=83=A1=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=81=AE=E6=89=8B=E5=89=8D=E3=81=AB=E7=A9=BA=E8=A1=8C?= =?UTF-8?q?=E3=82=92=E5=85=A5=E3=82=8C=E3=82=8B=20(SA1514)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/SearchWordDialog.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/SearchWordDialog.cs b/OpenTween/SearchWordDialog.cs index ea77868c7..49aaee26b 100644 --- a/OpenTween/SearchWordDialog.cs +++ b/OpenTween/SearchWordDialog.cs @@ -45,6 +45,7 @@ public enum SearchType /// タイムライン内を検索 /// Timeline, + /// /// Twitter検索 /// From a8d33ff3c9598e6dbce5b5431b84539cfca081d6 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 19:50:17 +0900 Subject: [PATCH 142/402] =?UTF-8?q?=E3=83=91=E3=82=BF=E3=83=BC=E3=83=B3?= =?UTF-8?q?=E3=83=9E=E3=83=83=E3=83=81=E3=83=B3=E3=82=B0=E3=82=92=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Models/PostClass.cs | 2 +- OpenTween/OpenURL.cs | 10 +++---- OpenTween/Tween.cs | 52 +++++++++++++---------------------- OpenTween/TweetFormatter.cs | 46 +++++++++++-------------------- OpenTween/Twitter.cs | 15 +++++----- 5 files changed, 47 insertions(+), 78 deletions(-) diff --git a/OpenTween/Models/PostClass.cs b/OpenTween/Models/PostClass.cs index b12ad2cdb..f65b5feab 100644 --- a/OpenTween/Models/PostClass.cs +++ b/OpenTween/Models/PostClass.cs @@ -56,7 +56,7 @@ public override int GetHashCode() => this.Longitude.GetHashCode() ^ this.Latitude.GetHashCode(); public override bool Equals(object obj) - => obj is StatusGeo && this.Equals((StatusGeo)obj); + => obj is StatusGeo geo && this.Equals(geo); public bool Equals(StatusGeo other) => this.Longitude == other.Longitude && this.Latitude == other.Longitude; diff --git a/OpenTween/OpenURL.cs b/OpenTween/OpenURL.cs index 064f621ab..c467c4214 100644 --- a/OpenTween/OpenURL.cs +++ b/OpenTween/OpenURL.cs @@ -136,15 +136,13 @@ public string Text { get { - if (this.linkText.StartsWith("@", StringComparison.Ordinal) - || this.linkText.StartsWith("@", StringComparison.Ordinal) - || this.linkText.StartsWith("#", StringComparison.Ordinal) - || this.linkText.StartsWith("#", StringComparison.Ordinal)) + if (this.linkText[0] is '@' or '@' or '#' or '#') return this.linkText; + if (this.linkText.TrimEnd('/') == this.Url.TrimEnd('/')) return this.Url; - else - return this.linkText + " >>> " + this.Url; + + return this.linkText + " >>> " + this.Url; } } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 17d94ba5a..428bafe3f 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1095,31 +1095,17 @@ private void TweenMain_Load(object sender, EventArgs e) //////////////////////////////////////////////////////////////////////////////// var sortOrder = (SortOrder)SettingManager.Common.SortOrder; - var mode = ComparerMode.Id; - switch (SettingManager.Common.SortColumn) - { - case 0: // 0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク - case 5: - case 6: - // ソートしない - mode = ComparerMode.Id; // Idソートに読み替え - break; - case 1: // ニックネーム - mode = ComparerMode.Nickname; - break; - case 2: // 本文 - mode = ComparerMode.Data; - break; - case 3: // 時刻=発言Id - mode = ComparerMode.Id; - break; - case 4: // 名前 - mode = ComparerMode.Name; - break; - case 7: // Source - mode = ComparerMode.Source; - break; - } + var mode = SettingManager.Common.SortColumn switch + { + // 0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク + 0 or 5 or 6 => ComparerMode.Id, // Idソートに読み替え + 1 => ComparerMode.Nickname, // ニックネーム + 2 => ComparerMode.Data, // 本文 + 3 => ComparerMode.Id, // 時刻=発言Id + 4 => ComparerMode.Name, // 名前 + 7 => ComparerMode.Source, // Source + _ => ComparerMode.Id, + }; this.statuses.SetSortMode(mode, sortOrder); //////////////////////////////////////////////////////////////////////////////// @@ -2266,14 +2252,14 @@ private async Task RefreshTabAsync(TabModel tab, bool backward) this.myStatusError = true; var tabType = tab switch { - HomeTabModel _ => "GetTimeline", - MentionsTabModel _ => "GetTimeline", - DirectMessagesTabModel _ => "GetDirectMessage", - FavoritesTabModel _ => "GetFavorites", - PublicSearchTabModel _ => "GetSearch", - UserTimelineTabModel _ => "GetUserTimeline", - ListTimelineTabModel _ => "GetListStatus", - RelatedPostsTabModel _ => "GetRelatedTweets", + HomeTabModel => "GetTimeline", + MentionsTabModel => "GetTimeline", + DirectMessagesTabModel => "GetDirectMessage", + FavoritesTabModel => "GetFavorites", + PublicSearchTabModel => "GetSearch", + UserTimelineTabModel => "GetUserTimeline", + ListTimelineTabModel => "GetListStatus", + RelatedPostsTabModel => "GetRelatedTweets", _ => tab.GetType().Name.Replace("Model", ""), }; this.StatusLabel.Text = $"Err:{ex.Message}({tabType})"; diff --git a/OpenTween/TweetFormatter.cs b/OpenTween/TweetFormatter.cs index eb066abf3..681ecd53e 100644 --- a/OpenTween/TweetFormatter.cs +++ b/OpenTween/TweetFormatter.cs @@ -72,16 +72,14 @@ private static IEnumerable AutoLinkHtmlInternal(string text, IEnumerable var targetText = text.Substring(startIndex, endIndex - startIndex); - if (entity is TwitterEntityUrl urlEntity) - yield return FormatUrlEntity(targetText, urlEntity, keepTco); - else if (entity is TwitterEntityHashtag hashtagEntity) - yield return FormatHashtagEntity(targetText, hashtagEntity); - else if (entity is TwitterEntityMention mentionEntity) - yield return FormatMentionEntity(targetText, mentionEntity); - else if (entity is TwitterEntityEmoji emojiEntity) - yield return FormatEmojiEntity(targetText, emojiEntity); - else - yield return T(E(targetText)); + yield return entity switch + { + TwitterEntityUrl urlEntity => FormatUrlEntity(targetText, urlEntity, keepTco), + TwitterEntityHashtag hashtagEntity => FormatHashtagEntity(targetText, hashtagEntity), + TwitterEntityMention mentionEntity => FormatMentionEntity(targetText, mentionEntity), + TwitterEntityEmoji emojiEntity => FormatEmojiEntity(targetText, emojiEntity), + _ => T(E(targetText)), + }; curIndex = endIndex; } @@ -194,27 +192,15 @@ private static string EscapeHtml(string text) { // 「<」「>」「&」「"」「'」についてエスケープ処理を施す // 参照: http://d.hatena.ne.jp/ockeghem/20070510/1178813849 - switch (c) + result.Append(c switch { - case '<': - result.Append("<"); - break; - case '>': - result.Append(">"); - break; - case '&': - result.Append("&"); - break; - case '"': - result.Append("""); - break; - case '\'': - result.Append("'"); - break; - default: - result.Append(c); - break; - } + '<' => "<", + '>' => ">", + '&' => "&", + '"' => """, + '\'' => "'", + _ => c, + }); } return result.ToString(); diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 2b92d22b3..915980225 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1800,14 +1800,13 @@ public static string CreateProfileImageUrl(string normalUrl, string size) public static string DecideProfileImageSize(int sizePx) { - if (sizePx <= 24) - return "mini"; - else if (sizePx <= 48) - return "normal"; - else if (sizePx <= 73) - return "bigger"; - else - return "original"; + return sizePx switch + { + <= 24 => "mini", + <= 48 => "normal", + <= 73 => "bigger", + _ => "original", + }; } public bool IsDisposed { get; private set; } = false; From 0d64996706aa94a558e61169bd76effd1ad840e9 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Mar 2022 20:09:56 +0900 Subject: [PATCH 143/402] =?UTF-8?q?MemberNotNullAttribute=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApiKey.cs | 4 ++-- OpenTween/Connection/TwitterApiConnection.cs | 8 +++++--- OpenTween/NullableAttributes.cs | 9 +++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/OpenTween/ApiKey.cs b/OpenTween/ApiKey.cs index a9c4f8759..c4e968263 100644 --- a/OpenTween/ApiKey.cs +++ b/OpenTween/ApiKey.cs @@ -65,7 +65,7 @@ private ApiKey(string password, string rawKey) /// /// 成功した場合は true、暗号化された API キーの復号に失敗した場合は false を返します /// - public bool TryGetValue([NotNullWhen(true)]out string output) + public bool TryGetValue([NotNullWhen(true)]out string? output) { try { @@ -74,7 +74,7 @@ public bool TryGetValue([NotNullWhen(true)]out string output) } catch (ApiKeyDecryptException) { - output = null!; + output = null; return false; } } diff --git a/OpenTween/Connection/TwitterApiConnection.cs b/OpenTween/Connection/TwitterApiConnection.cs index b21bd81a1..faa54ae38 100644 --- a/OpenTween/Connection/TwitterApiConnection.cs +++ b/OpenTween/Connection/TwitterApiConnection.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Net; @@ -55,9 +56,9 @@ public static string RestApiHost public string AccessSecret { get; } - internal HttpClient Http = null!; - internal HttpClient HttpUpload = null!; - internal HttpClient HttpStreaming = null!; + internal HttpClient Http; + internal HttpClient HttpUpload; + internal HttpClient HttpStreaming; private readonly ApiKey consumerKey; private readonly ApiKey consumerSecret; @@ -73,6 +74,7 @@ public TwitterApiConnection(ApiKey consumerKey, ApiKey consumerSecret, string ac Networking.WebProxyChanged += this.Networking_WebProxyChanged; } + [MemberNotNull(nameof(Http), nameof(HttpUpload), nameof(HttpStreaming))] private void InitializeHttpClients() { this.Http = InitializeHttpClient(this.consumerKey, this.consumerSecret, this.AccessToken, this.AccessSecret); diff --git a/OpenTween/NullableAttributes.cs b/OpenTween/NullableAttributes.cs index 6470366d6..f99ce63f4 100644 --- a/OpenTween/NullableAttributes.cs +++ b/OpenTween/NullableAttributes.cs @@ -41,4 +41,13 @@ internal sealed class MaybeNullWhenAttribute : Attribute public MaybeNullWhenAttribute(bool returnValue) => this.ReturnValue = returnValue; } + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false)] + internal sealed class MemberNotNullAttribute : Attribute + { + public string[] Members { get; } + + public MemberNotNullAttribute(params string[] members) + => this.Members = members; + } } From 09d068625f061bb91369c9fd237a1db14b4ea234 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 30 Mar 2022 01:05:39 +0900 Subject: [PATCH 144/402] =?UTF-8?q?=E3=83=AC=E3=82=B3=E3=83=BC=E3=83=89?= =?UTF-8?q?=E5=9E=8B=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/ToolStripAPIGaugeTest.cs | 6 +- OpenTween/Api/ApiLimit.cs | 53 +----- OpenTween/HookGlobalHotkey.cs | 16 +- OpenTween/IsExternalInit.cs | 29 +++ OpenTween/Models/PostClass.cs | 31 +-- OpenTween/Models/TabModel.cs | 16 +- OpenTween/MouseWheelMessageFilter.cs | 16 +- OpenTween/OpenTween.csproj | 1 + OpenTween/OpenURL.cs | 27 +-- OpenTween/SearchWordDialog.cs | 29 +-- OpenTween/TabsDialog.cs | 27 ++- OpenTween/Thumbnail/MapThumb.cs | 10 +- .../Thumbnail/Services/FoursquareCheckin.cs | 9 +- OpenTween/ToolStripLabelHistory.cs | 23 +-- OpenTween/Tween.cs | 179 +++++++----------- OpenTween/TweetDetailsView.cs | 7 +- 16 files changed, 175 insertions(+), 304 deletions(-) create mode 100644 OpenTween/IsExternalInit.cs diff --git a/OpenTween.Tests/ToolStripAPIGaugeTest.cs b/OpenTween.Tests/ToolStripAPIGaugeTest.cs index 8c13f5e6c..e9f3a3d61 100644 --- a/OpenTween.Tests/ToolStripAPIGaugeTest.cs +++ b/OpenTween.Tests/ToolStripAPIGaugeTest.cs @@ -211,9 +211,9 @@ public void OneBillionTest() toolStrip.GaugeHeight = 5; MyCommon.TwitterApiInfo.AccessLimit["/statuses/user_timeline"] = new ApiLimit( - limitCount: 1_000_000_000, - limitRemain: 999_999_999, - resetDate: now + TimeSpan.FromMinutes(15) + AccessLimitCount: 1_000_000_000, + AccessLimitRemain: 999_999_999, + AccessLimitResetDate: now + TimeSpan.FromMinutes(15) ); toolStrip.ApiEndpoint = "/statuses/user_timeline"; diff --git a/OpenTween/Api/ApiLimit.cs b/OpenTween/Api/ApiLimit.cs index 91f31fe96..16633e115 100644 --- a/OpenTween/Api/ApiLimit.cs +++ b/OpenTween/Api/ApiLimit.cs @@ -28,49 +28,12 @@ namespace OpenTween.Api { - public class ApiLimit - { - public ApiLimit(int limitCount, int limitRemain, DateTimeUtc resetDate) - : this(limitCount, limitRemain, resetDate, DateTimeUtc.Now) - { - } - - public ApiLimit(int limitCount, int limitRemain, DateTimeUtc resetDate, DateTimeUtc updatedAt) - { - this.AccessLimitCount = limitCount; - this.AccessLimitRemain = limitRemain; - this.AccessLimitResetDate = resetDate; - this.UpdatedAt = updatedAt; - } - - /// - /// API 実行回数制限の値 - /// - public int AccessLimitCount { get; } - - /// - /// API 実行回数制限までの残回数 - /// - public int AccessLimitRemain { get; } - - /// - /// API 実行回数制限がリセットされる日時 - /// - public DateTimeUtc AccessLimitResetDate { get; } - - /// - /// API 実行回数制限値を取得した日時 - /// - public DateTimeUtc UpdatedAt { get; } - - public override bool Equals(object? obj) - => this.Equals(obj as ApiLimit); - - public bool Equals(ApiLimit? obj) - => obj != null && this.AccessLimitCount == obj.AccessLimitCount && - this.AccessLimitRemain == obj.AccessLimitRemain && this.AccessLimitResetDate == obj.AccessLimitResetDate; - - public override int GetHashCode() - => this.AccessLimitCount ^ this.AccessLimitRemain ^ this.AccessLimitResetDate.GetHashCode(); - } + /// API 実行回数制限の値 + /// API 実行回数制限までの残回数 + /// API 実行回数制限がリセットされる日時 + public record ApiLimit( + int AccessLimitCount, + int AccessLimitRemain, + DateTimeUtc AccessLimitResetDate + ); } diff --git a/OpenTween/HookGlobalHotkey.cs b/OpenTween/HookGlobalHotkey.cs index 66460f5ec..ed3b8dfe6 100644 --- a/OpenTween/HookGlobalHotkey.cs +++ b/OpenTween/HookGlobalHotkey.cs @@ -38,18 +38,10 @@ public class HookGlobalHotkey : NativeWindow, IDisposable { private readonly Form targetForm; - private class KeyEventValue - { - public KeyEventArgs KeyEvent { get; } - - public int Value { get; } - - public KeyEventValue(KeyEventArgs keyEvent, int value) - { - this.KeyEvent = keyEvent; - this.Value = value; - } - } + private readonly record struct KeyEventValue( + KeyEventArgs KeyEvent, + int Value + ); private readonly Dictionary hotkeyID; diff --git a/OpenTween/IsExternalInit.cs b/OpenTween/IsExternalInit.cs new file mode 100644 index 000000000..49c27b35f --- /dev/null +++ b/OpenTween/IsExternalInit.cs @@ -0,0 +1,29 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +namespace System.Runtime.CompilerServices +{ + internal sealed class IsExternalInit + { + } +} diff --git a/OpenTween/Models/PostClass.cs b/OpenTween/Models/PostClass.cs index f65b5feab..b91ab0a69 100644 --- a/OpenTween/Models/PostClass.cs +++ b/OpenTween/Models/PostClass.cs @@ -40,33 +40,10 @@ namespace OpenTween.Models { public class PostClass : ICloneable { - public readonly struct StatusGeo : IEquatable - { - public double Longitude { get; } - - public double Latitude { get; } - - public StatusGeo(double longitude, double latitude) - { - this.Longitude = longitude; - this.Latitude = latitude; - } - - public override int GetHashCode() - => this.Longitude.GetHashCode() ^ this.Latitude.GetHashCode(); - - public override bool Equals(object obj) - => obj is StatusGeo geo && this.Equals(geo); - - public bool Equals(StatusGeo other) - => this.Longitude == other.Longitude && this.Latitude == other.Longitude; - - public static bool operator ==(StatusGeo left, StatusGeo right) - => left.Equals(right); - - public static bool operator !=(StatusGeo left, StatusGeo right) - => !left.Equals(right); - } + public readonly record struct StatusGeo( + double Longitude, + double Latitude + ); public string Nickname { get; set; } = ""; diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index 8d8cd1167..e546e5956 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -113,18 +113,10 @@ protected TabModel(string tabName) public abstract Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress); - private readonly struct TemporaryId - { - public long StatusId { get; } - - public bool Read { get; } - - public TemporaryId(long statusId, bool read) - { - this.StatusId = statusId; - this.Read = read; - } - } + private readonly record struct TemporaryId( + long StatusId, + bool Read + ); public virtual void AddPostQueue(PostClass post) { diff --git a/OpenTween/MouseWheelMessageFilter.cs b/OpenTween/MouseWheelMessageFilter.cs index 3001e37f9..fb4d545fb 100644 --- a/OpenTween/MouseWheelMessageFilter.cs +++ b/OpenTween/MouseWheelMessageFilter.cs @@ -75,18 +75,10 @@ public bool PreFilterMessage(ref Message m) return false; } - internal class MouseEvent - { - public Point ScreenLocation { get; } - - public int WheelDelta { get; } - - public MouseEvent(Point location, int delta) - { - this.ScreenLocation = location; - this.WheelDelta = delta; - } - } + internal readonly record struct MouseEvent( + Point ScreenLocation, + int WheelDelta + ); internal static MouseEvent ParseMessage(Message m) { diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index d5115412a..6ba66aecb 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -126,6 +126,7 @@ + diff --git a/OpenTween/OpenURL.cs b/OpenTween/OpenURL.cs index c467c4214..9cf2db015 100644 --- a/OpenTween/OpenURL.cs +++ b/OpenTween/OpenURL.cs @@ -121,36 +121,27 @@ private void UrlList_KeyDown(object sender, KeyEventArgs e) } } - public class OpenUrlItem + public readonly record struct OpenUrlItem( + string LinkText, + string Url, + string Href + ) { - private readonly string linkText; - - public OpenUrlItem(string linkText, string url, string href) - { - this.linkText = linkText; - this.Url = url; - this.Href = href; - } - public string Text { get { - if (this.linkText[0] is '@' or '@' or '#' or '#') - return this.linkText; + if (this.LinkText[0] is '@' or '@' or '#' or '#') + return this.LinkText; - if (this.linkText.TrimEnd('/') == this.Url.TrimEnd('/')) + if (this.LinkText.TrimEnd('/') == this.Url.TrimEnd('/')) return this.Url; - return this.linkText + " >>> " + this.Url; + return this.LinkText + " >>> " + this.Url; } } public override string ToString() => this.Href; - - public string Url { get; } - - public string Href { get; } } } diff --git a/OpenTween/SearchWordDialog.cs b/OpenTween/SearchWordDialog.cs index 49aaee26b..fedbe97aa 100644 --- a/OpenTween/SearchWordDialog.cs +++ b/OpenTween/SearchWordDialog.cs @@ -52,28 +52,13 @@ public enum SearchType Public, } - public class SearchOptions - { - public SearchType Type { get; } - - public string Query { get; } - - // タイムライン内検索のみで使用する - public bool NewTab { get; } - - public bool CaseSensitive { get; } - - public bool UseRegex { get; } - - public SearchOptions(SearchType type, string query, bool newTab, bool caseSensitive, bool useRegex) - { - this.Type = type; - this.Query = query; - this.NewTab = newTab; - this.CaseSensitive = caseSensitive; - this.UseRegex = useRegex; - } - } + public record SearchOptions( + SearchType Type, + string Query, + bool NewTab, // タイムライン内検索のみで使用する + bool CaseSensitive, + bool UseRegex + ); private SearchOptions? resultOptions = null; diff --git a/OpenTween/TabsDialog.cs b/OpenTween/TabsDialog.cs index 4f39e47a3..e432394ac 100644 --- a/OpenTween/TabsDialog.cs +++ b/OpenTween/TabsDialog.cs @@ -49,12 +49,11 @@ public bool MultiSelect } } - protected internal class TabListItem + protected internal record TabListItem( + string Label, + FilterTabModel? Tab + ) { - public FilterTabModel? Tab { get; set; } - - public string Label { get; set; } = ""; - public override string ToString() => this.Label; } @@ -79,22 +78,20 @@ protected void UpdateTabList() { this.TabList.SelectionMode = SelectionMode.One; - this.TabList.Items.Add(new TabListItem - { - Label = Properties.Resources.AddNewTabText1, - Tab = null, - }); + this.TabList.Items.Add(new TabListItem( + Label: Properties.Resources.AddNewTabText1, + Tab: null + )); } var tabs = this.tabInfo.Tabs.Append(this.tabInfo.MuteTab); foreach (var tab in tabs.OfType()) { - this.TabList.Items.Add(new TabListItem - { - Label = tab.TabName, - Tab = tab, - }); + this.TabList.Items.Add(new TabListItem( + Label: tab.TabName, + Tab: tab + )); } } diff --git a/OpenTween/Thumbnail/MapThumb.cs b/OpenTween/Thumbnail/MapThumb.cs index 810248dff..e4c558edf 100644 --- a/OpenTween/Thumbnail/MapThumb.cs +++ b/OpenTween/Thumbnail/MapThumb.cs @@ -57,12 +57,10 @@ public static MapThumb GetDefaultInstance() } } - public class GlobalLocation - { - public double Latitude { get; set; } - - public double Longitude { get; set; } - } + public record GlobalLocation( + double Latitude, + double Longitude + ); public enum MapProvider { diff --git a/OpenTween/Thumbnail/Services/FoursquareCheckin.cs b/OpenTween/Thumbnail/Services/FoursquareCheckin.cs index a51252efb..0cc2d32ba 100644 --- a/OpenTween/Thumbnail/Services/FoursquareCheckin.cs +++ b/OpenTween/Thumbnail/Services/FoursquareCheckin.cs @@ -206,11 +206,10 @@ public FoursquareCheckin(HttpClient? http, ApiKey clientId, ApiKey clientSecret) if (planetElm != null && planetElm.Value != "earth") return null; - return new GlobalLocation - { - Latitude = double.Parse(locationElm.Element("lat").Value, CultureInfo.InvariantCulture), - Longitude = double.Parse(locationElm.Element("lng").Value, CultureInfo.InvariantCulture), - }; + return new GlobalLocation( + Latitude: double.Parse(locationElm.Element("lat").Value, CultureInfo.InvariantCulture), + Longitude: double.Parse(locationElm.Element("lng").Value, CultureInfo.InvariantCulture) + ); } } } diff --git a/OpenTween/ToolStripLabelHistory.cs b/OpenTween/ToolStripLabelHistory.cs index f254cb9cb..b42d53db7 100644 --- a/OpenTween/ToolStripLabelHistory.cs +++ b/OpenTween/ToolStripLabelHistory.cs @@ -48,24 +48,13 @@ public enum LogLevel Highest = 256, } - public class LogEntry + public readonly record struct LogEntry( + LogLevel LogLevel, + DateTimeUtc Timestamp, + string Summary, + string Detail + ) { - public LogLevel LogLevel { get; } - - public DateTimeUtc Timestamp { get; } - - public string Summary { get; } - - public string Detail { get; } - - public LogEntry(LogLevel logLevel, DateTimeUtc timestamp, string summary, string detail) - { - this.LogLevel = logLevel; - this.Timestamp = timestamp; - this.Summary = summary; - this.Detail = detail; - } - public LogEntry(DateTimeUtc timestamp, string summary) : this(LogLevel.Debug, timestamp, summary, summary) { diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 428bafe3f..eafe66b14 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -294,20 +294,17 @@ public partial class TweenMain : OTBaseForm /// private ListViewItemCache? listItemCache = null; - internal class ListViewItemCache + /// アイテムをキャッシュする対象の + /// キャッシュする範囲の開始インデックス + /// キャッシュする範囲の終了インデックス + /// ャッシュされた範囲に対応する の組 + internal record class ListViewItemCache( + ListView TargetList, + int StartIndex, + int EndIndex, + (ListViewItem, PostClass)[] Cache + ) { - /// アイテムをキャッシュする対象の - public ListView TargetList { get; set; } = null!; - - /// キャッシュする範囲の開始インデックス - public int StartIndex { get; set; } - - /// キャッシュする範囲の終了インデックス - public int EndIndex { get; set; } - - /// キャッシュされた範囲に対応する の組 - public (ListViewItem, PostClass)[] Cache { get; set; } = null!; - /// キャッシュされたアイテムの件数 public int Count => this.EndIndex - this.StartIndex + 1; @@ -366,27 +363,18 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ private bool preventSmsCommand = true; // URL短縮のUndo用 - private struct UrlUndo - { - public string Before; - public string After; - } + private readonly record struct UrlUndo( + string Before, + string After + ); private List? urlUndoBuffer = null; - private readonly struct ReplyChain - { - public readonly long OriginalId; - public readonly long InReplyToId; - public readonly TabModel OriginalTab; - - public ReplyChain(long originalId, long inReplyToId, TabModel originalTab) - { - this.OriginalId = originalId; - this.InReplyToId = inReplyToId; - this.OriginalTab = originalTab; - } - } + private readonly record struct ReplyChain( + long OriginalId, + long InReplyToId, + TabModel OriginalTab + ); /// [, ]でのリプライ移動の履歴 private Stack? replyChains; @@ -417,27 +405,10 @@ internal enum SEARCHTYPE PrevSearch, } - private class StatusTextHistory - { - public string Status { get; } = ""; - - public (long StatusId, string ScreenName)? InReplyTo { get; } = null; - - /// 画像投稿サービス名 - public string ImageService { get; set; } = ""; - - public IMediaItem[]? MediaItems { get; set; } = null; - - public StatusTextHistory() - { - } - - public StatusTextHistory(string status, (long StatusId, string ScreenName)? inReplyTo) - { - this.Status = status; - this.InReplyTo = inReplyTo; - } - } + private readonly record struct StatusTextHistory( + string Status, + (long StatusId, string ScreenName)? InReplyTo = null + ); private void TweenMain_Activated(object sender, EventArgs e) { @@ -997,7 +968,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.recommendedStatusFooter = " [TWNv" + Regex.Replace(MyCommon.FileVersion.Replace(".", ""), "^0*", "") + "]"; - this.history.Add(new StatusTextHistory()); + this.history.Add(new StatusTextHistory("")); this.hisIdx = 0; this.inReplyTo = null; @@ -1456,12 +1427,10 @@ private void RefreshTimeline() this.HashSupl.AddRangeItem(this.tw.GetHashList()); } - internal struct ListViewScroll - { - public ScrollLockMode ScrollLockMode { get; set; } - - public long? TopItemStatusId { get; set; } - } + internal readonly record struct ListViewScroll( + ScrollLockMode ScrollLockMode, + long? TopItemStatusId + ); internal enum ScrollLockMode { @@ -1483,19 +1452,21 @@ internal enum ScrollLockMode /// private ListViewScroll SaveListViewScroll(DetailsListView listView, TabModel tab) { - var listScroll = new ListViewScroll - { - ScrollLockMode = this.GetScrollLockMode(listView), - }; + var lockMode = this.GetScrollLockMode(listView); + long? topItemStatusId = null; - if (listScroll.ScrollLockMode == ScrollLockMode.FixedToItem) + if (lockMode == ScrollLockMode.FixedToItem) { var topItemIndex = listView.TopItem?.Index ?? -1; if (topItemIndex != -1 && topItemIndex < tab.AllCount) - listScroll.TopItemStatusId = tab.GetStatusIdAt(topItemIndex); + topItemStatusId = tab.GetStatusIdAt(topItemIndex); } - return listScroll; + return new ListViewScroll + { + ScrollLockMode = lockMode, + TopItemStatusId = topItemStatusId, + }; } private ScrollLockMode GetScrollLockMode(DetailsListView listView) @@ -1537,14 +1508,11 @@ private ScrollLockMode GetScrollLockMode(DetailsListView listView) } } - internal struct ListViewSelection - { - public long[]? SelectedStatusIds { get; set; } - - public long? SelectionMarkStatusId { get; set; } - - public long? FocusedStatusId { get; set; } - } + internal readonly record struct ListViewSelection( + long[]? SelectedStatusIds, + long? SelectionMarkStatusId, + long? FocusedStatusId + ); /// /// の選択状態を として返します @@ -2146,7 +2114,7 @@ private async void PostButton_Click(object sender, EventArgs e) this.inReplyTo = null; this.StatusText.Text = ""; - this.history.Add(new StatusTextHistory()); + this.history.Add(new StatusTextHistory("")); this.hisIdx = this.history.Count - 1; if (!SettingManager.Common.FocusLockToStatusText) this.CurrentListView.Focus(); @@ -4704,13 +4672,12 @@ int FilterRange(int index) .Select(x => this.CreateItem(tab, posts[x])) .ToArray(); - var listCache = new ListViewItemCache - { - TargetList = this.CurrentListView, - StartIndex = startIndex, - EndIndex = endIndex, - Cache = Enumerable.Zip(listItems, posts, (x, y) => (x, y)).ToArray(), - }; + var listCache = new ListViewItemCache( + TargetList: this.CurrentListView, + StartIndex: startIndex, + EndIndex: endIndex, + Cache: Enumerable.Zip(listItems, posts, (x, y) => (x, y)).ToArray() + ); Interlocked.Exchange(ref this.listItemCache, listCache); } @@ -5373,17 +5340,11 @@ private void RunTweenUp() } } - public class VersionInfo - { - public Version Version { get; } - - public Uri DownloadUri { get; } - - public string ReleaseNote { get; } - - public VersionInfo(Version version, Uri downloadUri, string releaseNote) - => (this.Version, this.DownloadUri, this.ReleaseNote) = (version, downloadUri, releaseNote); - } + public readonly record struct VersionInfo( + Version Version, + Uri DownloadUri, + string ReleaseNote + ); /// /// OpenTween の最新バージョンの情報を取得します @@ -5404,11 +5365,12 @@ public async Task GetVersionInfoAsync() msgBody = Regex.Replace(msgBody, "(? CRLF - return new VersionInfo( - version: Version.Parse(msgHeader[0]), - downloadUri: new Uri(msgHeader[1]), - releaseNote: msgBody - ); + return new VersionInfo + { + Version = Version.Parse(msgHeader[0]), + DownloadUri = new Uri(msgHeader[1]), + ReleaseNote = msgBody, + }; } private async Task CheckNewVersion(bool startup = false) @@ -8762,8 +8724,6 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) if (!MyCommon.IsNullOrEmpty(result)) { - var undotmp = new UrlUndo(); - // 短縮 URL が生成されるまでの間に投稿欄から元の URL が削除されていたら中断する var origUrlIndex = this.StatusText.Text.IndexOf(tmp, StringComparison.Ordinal); if (origUrlIndex == -1) @@ -8773,8 +8733,11 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) this.StatusText.SelectedText = result; // undoバッファにセット - undotmp.Before = tmp; - undotmp.After = result; + var undo = new UrlUndo + { + Before = tmp, + After = result, + }; if (this.urlUndoBuffer == null) { @@ -8782,7 +8745,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) this.UrlUndoToolStripMenuItem.Enabled = true; } - this.urlUndoBuffer.Add(undotmp); + this.urlUndoBuffer.Add(undo); } } } @@ -8801,7 +8764,6 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) var tmp = mt.Result("${url}"); if (tmp.StartsWith("w", StringComparison.OrdinalIgnoreCase)) tmp = "http://" + tmp; - var undotmp = new UrlUndo(); // 選んだURLを選択(?) this.StatusText.Select(this.StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length); @@ -8855,8 +8817,11 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) this.StatusText.Select(origUrlIndex, mt.Result("${url}").Length); this.StatusText.SelectedText = result; // undoバッファにセット - undotmp.Before = mt.Result("${url}"); - undotmp.After = result; + var undo = new UrlUndo + { + Before = mt.Result("${url}"), + After = result, + }; if (this.urlUndoBuffer == null) { @@ -8864,7 +8829,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) this.UrlUndoToolStripMenuItem.Enabled = true; } - this.urlUndoBuffer.Add(undotmp); + this.urlUndoBuffer.Add(undo); } } } diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 4527fb4b5..d5819757d 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -877,9 +877,10 @@ private void CurrentTabToolStripMenuItem_Click(object sender, EventArgs e) var searchOptions = new SearchWordDialog.SearchOptions( SearchWordDialog.SearchType.Timeline, selText, - newTab: false, - caseSensitive: false, - useRegex: false); + NewTab: false, + CaseSensitive: false, + UseRegex: false + ); this.Owner.SearchDialog.ResultOptions = searchOptions; From 900b0008a6c9efd727fb02212911df20c30a126e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 30 Mar 2022 02:44:11 +0900 Subject: [PATCH 145/402] =?UTF-8?q?=E5=AE=9A=E6=95=B0=E6=96=87=E5=AD=97?= =?UTF-8?q?=E5=88=97=E3=81=AB=20string=20interpolation=20=E3=82=92?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Tween.cs | 4 ++-- OpenTween/Twitter.cs | 40 ++++++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index eafe66b14..1b481ef75 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -120,10 +120,10 @@ public partial class TweenMain : OTBaseForm + ""; private const string DetailHtmlFormatTemplateMono = - "" + DetailHtmlFormatHead + "
%CONTENT_HTML%
"; + $"{DetailHtmlFormatHead}
%CONTENT_HTML%
"; private const string DetailHtmlFormatTemplateNormal = - "" + DetailHtmlFormatHead + "

%CONTENT_HTML%

"; + $"{DetailHtmlFormatHead}

%CONTENT_HTML%

"; private string detailHtmlFormatPreparedTemplate = null!; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 915980225..d90efd163 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -76,42 +76,42 @@ public class Twitter : IDisposable private const string NonLatinHashtagChars = @"\u0400-\u04ff\u0500-\u0527\u1100-\u11ff\u3130-\u3185\uA960-\uA97F\uAC00-\uD7AF\uD7B0-\uD7FF"; private const string CJHashtagCharacters = @"\u30A1-\u30FA\u30FC\u3005\uFF66-\uFF9F\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\u3041-\u309A\u3400-\u4DBF\p{IsCJKUnifiedIdeographs}"; private const string HashtagBoundary = @"^|$|\s|「|」|。|\.|!"; - private const string HashtagAlpha = "[A-Za-z_" + LatinAccents + NonLatinHashtagChars + CJHashtagCharacters + "]"; - private const string HashtagAlphanumeric = "[A-Za-z0-9_" + LatinAccents + NonLatinHashtagChars + CJHashtagCharacters + "]"; - private const string HashtagTerminator = "[^A-Za-z0-9_" + LatinAccents + NonLatinHashtagChars + CJHashtagCharacters + "]"; - public const string Hashtag = "(" + HashtagBoundary + ")(#|#)(" + HashtagAlphanumeric + "*" + HashtagAlpha + HashtagAlphanumeric + "*)(?=" + HashtagTerminator + "|" + HashtagBoundary + ")"; + private const string HashtagAlpha = $"[A-Za-z_{LatinAccents}{NonLatinHashtagChars}{CJHashtagCharacters}]"; + private const string HashtagAlphanumeric = $"[A-Za-z0-9_{LatinAccents}{NonLatinHashtagChars}{CJHashtagCharacters}]"; + private const string HashtagTerminator = $"[^A-Za-z0-9_{LatinAccents}{NonLatinHashtagChars}{CJHashtagCharacters}]"; + public const string Hashtag = $"({HashtagBoundary})(#|#)({HashtagAlphanumeric}*{HashtagAlpha}{HashtagAlphanumeric}*)(?={HashtagTerminator}|{HashtagBoundary})"; // URL正規表現 private const string UrlValidPrecedingChars = @"(?:[^A-Za-z0-9@@$##\ufffe\ufeff\uffff\u202a-\u202e]|^)"; public const string UrlInvalidWithoutProtocolPrecedingChars = @"[-_./]$"; private const string UrlInvalidDomainChars = @"\!'#%&'\(\)*\+,\\\-\.\/:;<=>\?@\[\]\^_{|}~\$\u2000-\u200a\u0009-\u000d\u0020\u0085\u00a0\u1680\u180e\u2028\u2029\u202f\u205f\u3000\ufffe\ufeff\uffff\u202a-\u202e"; - private const string UrlValidDomainChars = @"[^" + UrlInvalidDomainChars + "]"; - private const string UrlValidSubdomain = @"(?:(?:" + UrlValidDomainChars + @"(?:[_-]|" + UrlValidDomainChars + @")*)?" + UrlValidDomainChars + @"\.)"; - private const string UrlValidDomainName = @"(?:(?:" + UrlValidDomainChars + @"(?:-|" + UrlValidDomainChars + @")*)?" + UrlValidDomainChars + @"\.)"; + private const string UrlValidDomainChars = $@"[^{UrlInvalidDomainChars}]"; + private const string UrlValidSubdomain = $@"(?:(?:{UrlValidDomainChars}(?:[_-]|{UrlValidDomainChars})*)?{UrlValidDomainChars}\.)"; + private const string UrlValidDomainName = $@"(?:(?:{UrlValidDomainChars}(?:-|{UrlValidDomainChars})*)?{UrlValidDomainChars}\.)"; private const string UrlValidGTLD = @"(?:(?:aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx)(?=[^0-9a-zA-Z]|$))"; private const string UrlValidCCTLD = @"(?:(?:ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)(?=[^0-9a-zA-Z]|$))"; private const string UrlValidPunycode = @"(?:xn--[0-9a-z]+)"; - private const string UrlValidDomain = @"(?" + UrlValidSubdomain + "*" + UrlValidDomainName + "(?:" + UrlValidGTLD + "|" + UrlValidCCTLD + ")|" + UrlValidPunycode + ")"; - public const string UrlValidAsciiDomain = @"(?:(?:[a-z0-9" + LatinAccents + @"]+)\.)+(?:" + UrlValidGTLD + "|" + UrlValidCCTLD + "|" + UrlValidPunycode + ")"; - public const string UrlInvalidShortDomain = "^" + UrlValidDomainName + UrlValidCCTLD + "$"; + private const string UrlValidDomain = $@"(?{UrlValidSubdomain}*{UrlValidDomainName}(?:{UrlValidGTLD}|{UrlValidCCTLD})|{UrlValidPunycode})"; + public const string UrlValidAsciiDomain = $@"(?:(?:[a-z0-9{LatinAccents}]+)\.)+(?:{UrlValidGTLD}|{UrlValidCCTLD}|{UrlValidPunycode})"; + public const string UrlInvalidShortDomain = $"^{UrlValidDomainName}{UrlValidCCTLD}$"; private const string UrlValidPortNumber = @"[0-9]+"; - private const string UrlValidGeneralPathChars = @"[a-z0-9!*';:=+,.$/%#\[\]\-_~|&" + LatinAccents + "]"; - private const string UrlBalanceParens = @"(?:\(" + UrlValidGeneralPathChars + @"+\))"; - private const string UrlValidPathEndingChars = @"(?:[+\-a-z0-9=_#/" + LatinAccents + "]|" + UrlBalanceParens + ")"; + private const string UrlValidGeneralPathChars = $@"[a-z0-9!*';:=+,.$/%#\[\]\-_~|&{LatinAccents}]"; + private const string UrlBalanceParens = $@"(?:\({UrlValidGeneralPathChars}+\))"; + private const string UrlValidPathEndingChars = $@"(?:[+\-a-z0-9=_#/{LatinAccents}]|{UrlBalanceParens})"; private const string Pth = "(?:" + "(?:" + - UrlValidGeneralPathChars + "*" + - "(?:" + UrlBalanceParens + UrlValidGeneralPathChars + "*)*" + + $"{UrlValidGeneralPathChars}*" + + $"(?:{UrlBalanceParens}{UrlValidGeneralPathChars}*)*" + UrlValidPathEndingChars + - ")|(?:@" + UrlValidGeneralPathChars + "+/)" + + $")|(?:@{UrlValidGeneralPathChars}+/)" + ")"; private const string Qry = @"(?\?[a-z0-9!?*'();:&=+$/%#\[\]\-_.,~|]*[a-z0-9_&=#/])?"; - public const string RgUrl = @"(?" + UrlValidPrecedingChars + ")" + + public const string RgUrl = $@"(?{UrlValidPrecedingChars})" + "(?(?https?://)?" + - "(?" + UrlValidDomain + ")" + - "(?::" + UrlValidPortNumber + ")?" + - "(?/" + Pth + "*)?" + + $"(?{UrlValidDomain})" + + $"(?::{UrlValidPortNumber})?" + + $"(?/{Pth}*)?" + Qry + ")"; From 985afa29228e3537b065f3b0fe0f52e0cf814194 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 6 Feb 2022 08:57:10 +0900 Subject: [PATCH 146/402] =?UTF-8?q?MemoryImage.Clone()=20=E3=81=A7?= =?UTF-8?q?=E5=86=85=E9=83=A8=E3=81=AE=20byte[]=20=E3=82=92=E3=82=B3?= =?UTF-8?q?=E3=83=94=E3=83=BC=E3=81=9B=E3=81=9A=E3=81=AB=E5=86=8D=E5=88=A9?= =?UTF-8?q?=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/MemoryImageTest.cs | 42 +++++++ OpenTween/MemoryImage.cs | 186 +++++++++-------------------- OpenTween/TweetDetailsView.cs | 3 +- 3 files changed, 98 insertions(+), 133 deletions(-) diff --git a/OpenTween.Tests/MemoryImageTest.cs b/OpenTween.Tests/MemoryImageTest.cs index 4681b604c..b038455c0 100644 --- a/OpenTween.Tests/MemoryImageTest.cs +++ b/OpenTween.Tests/MemoryImageTest.cs @@ -53,6 +53,48 @@ public void ImageFormat_CopyFromImageTest() Assert.Equal(".png", image.ImageFormatExt); } + [Fact] + public async Task CopyFromStream_Test() + { + using var stream = File.OpenRead("Resources/re.gif"); + using var memstream = new MemoryStream(); + await stream.CopyToAsync(memstream) + .ConfigureAwait(false); + + stream.Seek(0, SeekOrigin.Begin); + + using var image = MemoryImage.CopyFromStream(stream); + Assert.Equal(memstream.ToArray(), image.Stream.ToArray()); + } + + [Fact] + public async Task CopyFromStreamAsync_Test() + { + using var stream = File.OpenRead("Resources/re.gif"); + using var memstream = new MemoryStream(); + await stream.CopyToAsync(memstream) + .ConfigureAwait(false); + + stream.Seek(0, SeekOrigin.Begin); + + using var image = await MemoryImage.CopyFromStreamAsync(stream) + .ConfigureAwait(false); + Assert.Equal(memstream.ToArray(), image.Stream.ToArray()); + } + + [Fact] + public async Task CopyFromBytes_Test() + { + using var stream = File.OpenRead("Resources/re.gif"); + using var memstream = new MemoryStream(); + await stream.CopyToAsync(memstream) + .ConfigureAwait(false); + var imageBytes = memstream.ToArray(); + + using var image = MemoryImage.CopyFromBytes(imageBytes); + Assert.Equal(imageBytes, image.Stream.ToArray()); + } + [Fact] public void CopyFromImage_Test() { diff --git a/OpenTween/MemoryImage.cs b/OpenTween/MemoryImage.cs index cc1150b0f..06d9a5df1 100644 --- a/OpenTween/MemoryImage.cs +++ b/OpenTween/MemoryImage.cs @@ -44,41 +44,65 @@ namespace OpenTween /// public class MemoryImage : ICloneable, IDisposable, IEquatable { + private readonly byte[] buffer; + private readonly int bufferOffset; + private readonly int bufferCount; private readonly Image image; + private static readonly Dictionary ExtensionByFormat = new() + { + { ImageFormat.Bmp, ".bmp" }, + { ImageFormat.Emf, ".emf" }, + { ImageFormat.Gif, ".gif" }, + { ImageFormat.Icon, ".ico" }, + { ImageFormat.Jpeg, ".jpg" }, + { ImageFormat.MemoryBmp, ".bmp" }, + { ImageFormat.Png, ".png" }, + { ImageFormat.Tiff, ".tiff" }, + { ImageFormat.Wmf, ".wmf" }, + }; + /// /// ストリームから読みだされる画像データが不正な場合にスローされる /// - protected MemoryImage(MemoryStream stream) + protected MemoryImage(byte[] buffer, int offset, int count) + { + try + { + this.buffer = buffer; + this.bufferOffset = offset; + this.bufferCount = count; + + this.Stream = new(buffer, offset, count, writable: false); + this.image = this.CreateImage(this.Stream); + } + catch + { + this.Stream?.Dispose(); + throw; + } + } + + private Image CreateImage(Stream stream) { try { - this.image = Image.FromStream(stream); + return Image.FromStream(stream); } catch (ArgumentException e) { - stream.Dispose(); throw new InvalidImageException("Invalid image", e); } catch (OutOfMemoryException e) { // GDI+ がサポートしない画像形式で OutOfMemoryException がスローされる場合があるらしい - stream.Dispose(); throw new InvalidImageException("Invalid image?", e); } catch (ExternalException e) { // 「GDI+ で汎用エラーが発生しました」という大雑把な例外がスローされる場合があるらしい - stream.Dispose(); throw new InvalidImageException("Invalid image?", e); } - catch (Exception) - { - stream.Dispose(); - throw; - } - - this.Stream = stream; } /// @@ -115,71 +139,19 @@ public ImageFormat ImageFormat /// MemoryImage が保持している画像のフォーマットに相当する拡張子 (ピリオド付き) /// public string ImageFormatExt - { - get - { - var format = this.ImageFormat; - - // ImageFormat は == で正しく比較できないため Equals を使用する必要がある - if (format.Equals(ImageFormat.Bmp)) - return ".bmp"; - if (format.Equals(ImageFormat.Emf)) - return ".emf"; - if (format.Equals(ImageFormat.Gif)) - return ".gif"; - if (format.Equals(ImageFormat.Icon)) - return ".ico"; - if (format.Equals(ImageFormat.Jpeg)) - return ".jpg"; - if (format.Equals(ImageFormat.MemoryBmp)) - return ".bmp"; - if (format.Equals(ImageFormat.Png)) - return ".png"; - if (format.Equals(ImageFormat.Tiff)) - return ".tiff"; - if (format.Equals(ImageFormat.Wmf)) - return ".wmf"; - - // 対応する形式がなければ空文字列を返す - // (上記以外のフォーマットは Image.FromStream を通過できないため、ここが実行されることはまず無い) - return string.Empty; - } - } + => MemoryImage.ExtensionByFormat.TryGetValue(this.ImageFormat, out var ext) ? ext : ""; /// /// MemoryImage インスタンスを複製します /// - /// - /// メソッド実行中にストリームのシークが行われないよう注意して下さい。 - /// 特に PictureBox で Gif アニメーションを表示している場合は Enabled に false をセットするなどして更新を止めて下さい。 - /// /// 複製された MemoryImage public MemoryImage Clone() - { - this.Stream.Seek(0, SeekOrigin.Begin); - - return MemoryImage.CopyFromStream(this.Stream); - } - - /// - /// MemoryImage インスタンスを非同期に複製します - /// - /// - /// メソッド実行中にストリームのシークが行われないよう注意して下さい。 - /// 特に PictureBox で Gif アニメーションを表示している場合は Enabled に false をセットするなどして更新を止めて下さい。 - /// - /// 複製された MemoryImage を返すタスク - public Task CloneAsync() - { - this.Stream.Seek(0, SeekOrigin.Begin); - - return MemoryImage.CopyFromStreamAsync(this.Stream); - } + => new(this.buffer, this.bufferOffset, this.bufferCount); public override int GetHashCode() { using var sha1service = new System.Security.Cryptography.SHA1CryptoServiceProvider(); - var hash = sha1service.ComputeHash(this.Stream.GetBuffer(), 0, (int)this.Stream.Length); + var hash = sha1service.ComputeHash(this.buffer, this.bufferOffset, this.bufferCount); return Convert.ToBase64String(hash).GetHashCode(); } @@ -195,23 +167,13 @@ public bool Equals(MemoryImage? other) return false; // それぞれが保持する MemoryStream の内容が等しいことを検証する + var selfBuffer = new ArraySegment(this.buffer, this.bufferOffset, this.bufferCount); + var otherBuffer = new ArraySegment(other.buffer, other.bufferOffset, other.bufferCount); - var selfLength = this.Stream.Length; - var otherLength = other.Stream.Length; - - if (selfLength != otherLength) + if (selfBuffer.Count != otherBuffer.Count) return false; - var selfBuffer = this.Stream.GetBuffer(); - var otherBuffer = other.Stream.GetBuffer(); - - for (var pos = 0L; pos < selfLength; pos++) - { - if (selfBuffer[pos] != otherBuffer[pos]) - return false; - } - - return true; + return selfBuffer.Zip(otherBuffer, (x, y) => x == y).All(x => x); } object ICloneable.Clone() @@ -253,20 +215,11 @@ public void Dispose() /// 不正な画像データが入力された場合 public static MemoryImage CopyFromStream(Stream stream) { - MemoryStream? memstream = null; - try - { - memstream = new MemoryStream(); + using var memstream = new MemoryStream(); - stream.CopyTo(memstream); + stream.CopyTo(memstream); - return new MemoryImage(memstream); - } - catch - { - memstream?.Dispose(); - throw; - } + return new(memstream.GetBuffer(), 0, (int)memstream.Length); } /// @@ -279,22 +232,14 @@ public static MemoryImage CopyFromStream(Stream stream) /// 読み込む対象となる Stream /// 作成された MemoryImage を返すタスク /// 不正な画像データが入力された場合 - public static async Task CopyFromStreamAsync(Stream stream) + public static async Task CopyFromStreamAsync(Stream stream, int capacity = 0) { - MemoryStream? memstream = null; - try - { - memstream = new MemoryStream(); + using var memstream = new MemoryStream(capacity); - await stream.CopyToAsync(memstream).ConfigureAwait(false); + await stream.CopyToAsync(memstream) + .ConfigureAwait(false); - return new MemoryImage(memstream); - } - catch - { - memstream?.Dispose(); - throw; - } + return new(memstream.GetBuffer(), 0, (int)memstream.Length); } /// @@ -304,19 +249,7 @@ public static async Task CopyFromStreamAsync(Stream stream) /// 作成された MemoryImage /// 不正な画像データが入力された場合 public static MemoryImage CopyFromBytes(byte[] bytes) - { - MemoryStream? memstream = null; - try - { - memstream = new MemoryStream(bytes); - return new MemoryImage(memstream); - } - catch - { - memstream?.Dispose(); - throw; - } - } + => new(bytes, 0, bytes.Length); /// /// Image インスタンスから MemoryImage を作成します @@ -328,20 +261,11 @@ public static MemoryImage CopyFromBytes(byte[] bytes) /// 作成された MemoryImage public static MemoryImage CopyFromImage(Image image) { - MemoryStream? memstream = null; - try - { - memstream = new MemoryStream(); + using var memstream = new MemoryStream(); - image.Save(memstream, ImageFormat.Png); + image.Save(memstream, ImageFormat.Png); - return new MemoryImage(memstream); - } - catch - { - memstream?.Dispose(); - throw; - } + return new(memstream.GetBuffer(), 0, (int)memstream.Length); } } diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index d5819757d..8a3e0d3bf 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -278,8 +278,7 @@ await this.UserPicture.SetImageFromTask( var image = await this.IconCache.DownloadImageAsync(imageUrl, force) .ConfigureAwait(false); - return await image.CloneAsync() - .ConfigureAwait(false); + return image.Clone(); }, useStatusImage: false ); From 6034b349bd2c90835d54d7dea593b918f3da622a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 6 Feb 2022 09:09:28 +0900 Subject: [PATCH 147/402] =?UTF-8?q?=E3=83=97=E3=83=AD=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E7=94=BB=E5=83=8F=E3=81=AE=E6=8F=8F=E7=94=BB?= =?UTF-8?q?=E3=81=AB=E5=A4=B1=E6=95=97=E3=81=97=E3=81=9F=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AB=E7=94=BB=E5=83=8F=E3=82=92=E5=86=8D=E5=8F=96=E5=BE=97?= =?UTF-8?q?=E3=81=97=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ImageListViewItem.cs | 16 +++++----------- OpenTween/Tween.cs | 1 - 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/OpenTween/ImageListViewItem.cs b/OpenTween/ImageListViewItem.cs index 5d3a84ffa..d66d6a614 100644 --- a/OpenTween/ImageListViewItem.cs +++ b/OpenTween/ImageListViewItem.cs @@ -88,27 +88,27 @@ protected ImageListViewItem(SerializationInfo info, StreamingContext context) return Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); } - public Task GetImageAsync(bool force = false) + public Task GetImageAsync() { if (this.imageTask == null || this.imageTask.IsCompleted) { - this.imageTask = this.GetImageAsyncInternal(force); + this.imageTask = this.GetImageAsyncInternal(); } return this.imageTask; } - private async Task GetImageAsyncInternal(bool force) + private async Task GetImageAsyncInternal() { if (MyCommon.IsNullOrEmpty(this.imageUrl) || this.imageCache == null) return; - if (!force && this.imageReference.Target != null) + if (this.imageReference.Target != null) return; try { - var image = await this.imageCache.DownloadImageAsync(this.imageUrl, force); + var image = await this.imageCache.DownloadImageAsync(this.imageUrl); this.imageReference.Target = image; @@ -135,11 +135,5 @@ private async Task GetImageAsyncInternal(bool force) public MemoryImage Image => (MemoryImage)this.imageReference.Target; - - public Task RefreshImageAsync() - { - this.imageReference.Target = null; - return this.GetImageAsync(true); - } } } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 1b481ef75..1bcf361bf 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -4979,7 +4979,6 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) } catch (ArgumentException) { - item.RefreshImageAsync(); } } } From 142c8c3b586226d15ed61a6c6f1e880605e9ca47 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 3 Apr 2022 09:38:20 +0900 Subject: [PATCH 148/402] =?UTF-8?q?AppVeyor=E3=81=A7=E3=81=AE=E9=87=8D?= =?UTF-8?q?=E8=A4=87=E3=81=97=E3=81=9F=E3=83=93=E3=83=AB=E3=83=89=E3=82=BF?= =?UTF-8?q?=E3=82=B9=E3=82=AF=E3=82=92=E6=8A=91=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index bf01707fb..8b24a7d7d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,6 +18,11 @@ matrix: - RELEASE_TAG: 'true' configuration: Debug +branches: + only: + - develop + - release + for: - # for dev build matrix: From a7e6cc38404d13868fda377edf1ddf7833c6859c Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 3 Apr 2022 22:10:35 +0900 Subject: [PATCH 149/402] =?UTF-8?q?=E3=83=8F=E3=83=B3=E3=83=89=E3=83=AB?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84=E4=BE=8B=E5=A4=96=E3=81=AE?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92ErrorReportHandler=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 68 ++---------------- OpenTween/ErrorReportHandler.cs | 124 ++++++++++++++++++++++++++++++++ OpenTween/OpenTween.csproj | 1 + 3 files changed, 130 insertions(+), 63 deletions(-) create mode 100644 OpenTween/ErrorReportHandler.cs diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index f05643a16..9c145e9af 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -33,11 +33,9 @@ using System.Globalization; using System.IO; using System.Linq; -using System.Reflection; using System.Security.Principal; using System.Text.RegularExpressions; using System.Threading; -using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.Win32; using OpenTween.Setting; @@ -63,6 +61,11 @@ internal class ApplicationEvents [STAThread] public static int Main(string[] args) { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + + using var errorReportHandler = new ErrorReportHandler(); + WarnIfApiKeyError(); WarnIfRunAsAdministrator(); @@ -95,17 +98,6 @@ public static int Main(string[] args) return 1; } - TaskScheduler.UnobservedTaskException += (s, e) => - { - e.SetObserved(); - OnUnhandledException(e.Exception.Flatten()); - }; - Application.ThreadException += (s, e) => OnUnhandledException(e.Exception); - AppDomain.CurrentDomain.UnhandledException += (s, e) => OnUnhandledException((Exception)e.ExceptionObject); - AsyncTimer.UnhandledException += (s, e) => OnUnhandledException(e.Exception); - - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); Application.Run(new TweenMain()); mt.ReleaseMutex(); @@ -214,56 +206,6 @@ private static void TryActivatePreviousWindow() } } - private static void OnUnhandledException(Exception ex) - { - if (CheckIgnorableError(ex)) - return; - - if (MyCommon.ExceptionOut(ex)) - { - Application.Exit(); - } - } - - /// - /// 無視しても問題のない既知の例外であれば true を返す - /// - private static bool CheckIgnorableError(Exception ex) - { -#if DEBUG - return false; -#else - if (ex is AggregateException aggregated) - { - if (aggregated.InnerExceptions.Count != 1) - return false; - - ex = aggregated.InnerExceptions.Single(); - } - - switch (ex) - { - case System.Net.WebException webEx: - // SSL/TLS のネゴシエーションに失敗した場合に発生する。なぜかキャッチできない例外 - // https://osdn.net/ticket/browse.php?group_id=6526&tid=37432 - if (webEx.Status == System.Net.WebExceptionStatus.SecureChannelFailure) - return true; - break; - case System.Threading.Tasks.TaskCanceledException cancelEx: - // ton.twitter.com の画像でタイムアウトした場合、try-catch で例外がキャッチできない - // https://osdn.net/ticket/browse.php?group_id=6526&tid=37433 - var stackTrace = new System.Diagnostics.StackTrace(cancelEx); - var lastFrameMethod = stackTrace.GetFrame(stackTrace.FrameCount - 1).GetMethod(); - if (lastFrameMethod.ReflectedType == typeof(Connection.TwitterApiConnection) && - lastFrameMethod.Name == nameof(Connection.TwitterApiConnection.GetStreamAsync)) - return true; - break; - } - - return false; -#endif - } - public static void InitCulture() { var currentCulture = CultureInfo.CurrentUICulture; diff --git a/OpenTween/ErrorReportHandler.cs b/OpenTween/ErrorReportHandler.cs new file mode 100644 index 000000000..af9d572f6 --- /dev/null +++ b/OpenTween/ErrorReportHandler.cs @@ -0,0 +1,124 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using OpenTween.Connection; + +namespace OpenTween +{ + public sealed class ErrorReportHandler : IDisposable + { + public bool IsDisposed { get; private set; } = false; + + public ErrorReportHandler() + => this.RegisterHandlers(); + + private void RegisterHandlers() + { + TaskScheduler.UnobservedTaskException += this.TaskScheduler_UnobservedTaskException; + AsyncTimer.UnhandledException += this.AsyncTimer_UnhandledException; + Application.ThreadException += this.Application_ThreadException; + AppDomain.CurrentDomain.UnhandledException += this.AppDomain_UnhandledException; + } + + private void UnregisterHandlers() + { + TaskScheduler.UnobservedTaskException -= this.TaskScheduler_UnobservedTaskException; + AsyncTimer.UnhandledException -= this.AsyncTimer_UnhandledException; + Application.ThreadException -= this.Application_ThreadException; + AppDomain.CurrentDomain.UnhandledException -= this.AppDomain_UnhandledException; + } + + private void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) + { + e.SetObserved(); + this.OnUnhandledException(e.Exception.Flatten()); + } + + private void AsyncTimer_UnhandledException(object sender, ThreadExceptionEventArgs e) + => this.OnUnhandledException(e.Exception); + + private void Application_ThreadException(object sender, ThreadExceptionEventArgs e) + => this.OnUnhandledException(e.Exception); + + private void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + => this.OnUnhandledException((Exception)e.ExceptionObject); + + private void OnUnhandledException(Exception ex) + { +#if !DEBUG + if (ErrorReportHandler.IsExceptionIgnorable(ex)) + return; +#endif + + if (MyCommon.ExceptionOut(ex)) + Application.Exit(); + } + + public void Dispose() + { + if (this.IsDisposed) + return; + + this.IsDisposed = true; + this.UnregisterHandlers(); + } + + /// + /// 無視しても問題のない既知の例外であれば true を返す + /// + public static bool IsExceptionIgnorable(Exception ex) + { + if (ex is AggregateException aggregated) + return aggregated.InnerExceptions.All(x => IsExceptionIgnorable(x)); + + if (ex is WebException webEx) + { + // SSL/TLS のネゴシエーションに失敗した場合に発生する。なぜかキャッチできない例外 + // https://osdn.net/ticket/browse.php?group_id=6526&tid=37432 + if (webEx.Status == WebExceptionStatus.SecureChannelFailure) + return true; + } + + if (ex is TaskCanceledException cancelEx) + { + // ton.twitter.com の画像でタイムアウトした場合、try-catch で例外がキャッチできない + // https://osdn.net/ticket/browse.php?group_id=6526&tid=37433 + var stackTrace = new StackTrace(cancelEx); + var lastFrameMethod = stackTrace.GetFrame(stackTrace.FrameCount - 1).GetMethod(); + var matchClass = lastFrameMethod.ReflectedType == typeof(TwitterApiConnection); + var matchMethod = lastFrameMethod.Name == nameof(TwitterApiConnection.GetStreamAsync); + if (matchClass && matchMethod) + return true; + } + + return false; + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 6ba66aecb..57f7ca161 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -126,6 +126,7 @@ + From 1db9934199e42741447cbd24b24615016114312a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 3 Apr 2022 22:44:19 +0900 Subject: [PATCH 150/402] =?UTF-8?q?=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=83=B3=E5=BC=95=E6=95=B0=E3=81=AE=E3=83=91?= =?UTF-8?q?=E3=83=BC=E3=82=B9=E5=87=A6=E7=90=86=E3=82=92CommandLineArgs?= =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/ApplicationEventsTest.cs | 77 ------------------- OpenTween.Tests/CommandLineArgsTest.cs | 97 ++++++++++++++++++++++++ OpenTween/ApplicationEvents.cs | 25 +----- OpenTween/CommandLineArgs.cs | 82 ++++++++++++++++++++ OpenTween/OpenTween.csproj | 1 + 5 files changed, 183 insertions(+), 99 deletions(-) create mode 100644 OpenTween.Tests/CommandLineArgsTest.cs create mode 100644 OpenTween/CommandLineArgs.cs diff --git a/OpenTween.Tests/ApplicationEventsTest.cs b/OpenTween.Tests/ApplicationEventsTest.cs index 6472dc973..8bf75c712 100644 --- a/OpenTween.Tests/ApplicationEventsTest.cs +++ b/OpenTween.Tests/ApplicationEventsTest.cs @@ -31,83 +31,6 @@ namespace OpenTween { public class ApplicationEventsTest { - [Fact] - public void ParseArguments_NoOptionsTest() - { - var args = new string[] { }; - - Assert.Empty(ApplicationEvents.ParseArguments(args)); - } - - [Fact] - public void ParseArguments_SingleOptionTest() - { - var args = new[] { "/foo" }; - - Assert.Equal(new Dictionary - { - ["foo"] = "", - }, - ApplicationEvents.ParseArguments(args)); - } - - [Fact] - public void ParseArguments_MultipleOptionsTest() - { - var args = new[] { "/foo", "/bar" }; - - Assert.Equal(new Dictionary - { - ["foo"] = "", - ["bar"] = "", - }, - ApplicationEvents.ParseArguments(args)); - } - - [Fact] - public void ParseArguments_OptionWithArgumentTest() - { - var args = new[] { "/foo:hogehoge" }; - - Assert.Equal(new Dictionary - { - ["foo"] = "hogehoge", - }, - ApplicationEvents.ParseArguments(args)); - } - - [Fact] - public void ParseArguments_OptionWithEmptyArgumentTest() - { - var args = new[] { "/foo:" }; - - Assert.Equal(new Dictionary - { - ["foo"] = "", - }, - ApplicationEvents.ParseArguments(args)); - } - - [Fact] - public void ParseArguments_IgroreInvalidOptionsTest() - { - var args = new string[] { "--foo", "/" }; - - Assert.Empty(ApplicationEvents.ParseArguments(args)); - } - - [Fact] - public void ParseArguments_DuplicateOptionsTest() - { - var args = new[] { "/foo:abc", "/foo:123" }; - - Assert.Equal(new Dictionary - { - ["foo"] = "123", - }, - ApplicationEvents.ParseArguments(args)); - } - [Theory] [InlineData("ja-JP", "ja-JP")] [InlineData("fr-FR", "en")] // 対応するカルチャが無い場合は en にフォールバックする diff --git a/OpenTween.Tests/CommandLineArgsTest.cs b/OpenTween.Tests/CommandLineArgsTest.cs new file mode 100644 index 000000000..128b8fd18 --- /dev/null +++ b/OpenTween.Tests/CommandLineArgsTest.cs @@ -0,0 +1,97 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using Xunit; + +namespace OpenTween +{ + public class CommandLineArgsTest + { + [Fact] + public void ParseArguments_NoOptionsTest() + { + var args = new string[] { }; + var parsedArgs = new CommandLineArgs(args); + + Assert.Empty(parsedArgs); + } + + [Fact] + public void ParseArguments_SingleOptionTest() + { + var args = new[] { "/foo" }; + var parsedArgs = new CommandLineArgs(args); + + Assert.Single(parsedArgs); + Assert.Equal("", parsedArgs["foo"]); + } + + [Fact] + public void ParseArguments_MultipleOptionsTest() + { + var args = new[] { "/foo", "/bar" }; + var parsedArgs = new CommandLineArgs(args); + + Assert.Equal(2, parsedArgs.Count); + Assert.Equal("", parsedArgs["foo"]); + Assert.Equal("", parsedArgs["bar"]); + } + + [Fact] + public void ParseArguments_OptionWithArgumentTest() + { + var args = new[] { "/foo:hogehoge" }; + var parsedArgs = new CommandLineArgs(args); + + Assert.Single(parsedArgs); + Assert.Equal("hogehoge", parsedArgs["foo"]); + } + + [Fact] + public void ParseArguments_OptionWithEmptyArgumentTest() + { + var args = new[] { "/foo:" }; + var parsedArgs = new CommandLineArgs(args); + + Assert.Single(parsedArgs); + Assert.Equal("", parsedArgs["foo"]); + } + + [Fact] + public void ParseArguments_IgroreInvalidOptionsTest() + { + var args = new string[] { "--foo", "/" }; + var parsedArgs = new CommandLineArgs(args); + + Assert.Empty(parsedArgs); + } + + [Fact] + public void ParseArguments_DuplicateOptionsTest() + { + var args = new[] { "/foo:abc", "/foo:123" }; + var parsedArgs = new CommandLineArgs(args); + + Assert.Single(parsedArgs); + Assert.Equal("123", parsedArgs["foo"]); + } + } +} diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 9c145e9af..d47232602 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -28,13 +28,11 @@ #nullable enable using System; -using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Security.Principal; -using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; using Microsoft.Win32; @@ -53,7 +51,7 @@ internal class ApplicationEvents /// /// 起動時に指定されたオプションを取得します /// - public static IDictionary StartupOptions { get; private set; } = null!; + public static CommandLineArgs StartupOptions { get; private set; } = null!; /// /// アプリケーションのメイン エントリ ポイントです。 @@ -66,6 +64,8 @@ public static int Main(string[] args) using var errorReportHandler = new ErrorReportHandler(); + StartupOptions = new(args); + WarnIfApiKeyError(); WarnIfRunAsAdministrator(); @@ -76,8 +76,6 @@ public static int Main(string[] args) return 1; } - StartupOptions = ParseArguments(args); - if (!SetConfigDirectoryPath()) return 1; @@ -158,23 +156,6 @@ private static bool CheckRuntimeVersion() return releaseKey >= 461808; } - /// - /// “/key:value”形式の起動オプションを解釈し IDictionary に変換する - /// - /// - /// 不正な形式のオプションは除外されます。 - /// また、重複したキーのオプションが入力された場合は末尾に書かれたオプションが採用されます。 - /// - internal static IDictionary ParseArguments(IEnumerable arguments) - { - var optionPattern = new Regex(@"^/(.+?)(?::(.*))?$"); - - return arguments.Select(x => optionPattern.Match(x)) - .Where(x => x.Success) - .GroupBy(x => x.Groups[1].Value) - .ToDictionary(x => x.Key, x => x.Last().Groups[2].Value); - } - private static void TryActivatePreviousWindow() { // 実行中の同じアプリケーションのウィンドウ・ハンドルの取得 diff --git a/OpenTween/CommandLineArgs.cs b/OpenTween/CommandLineArgs.cs new file mode 100644 index 000000000..1d0708c0b --- /dev/null +++ b/OpenTween/CommandLineArgs.cs @@ -0,0 +1,82 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Text.RegularExpressions; + +namespace OpenTween +{ + public class CommandLineArgs : IReadOnlyDictionary + { + private readonly Dictionary parsedArgs; + + public CommandLineArgs(string[] args) + => this.parsedArgs = this.ParseArguments(args); + + public string this[string key] + => this.parsedArgs[key]; + + public IEnumerable Keys + => this.parsedArgs.Keys; + + public IEnumerable Values + => this.parsedArgs.Values; + + public int Count + => this.parsedArgs.Count; + + public bool ContainsKey(string key) + => this.parsedArgs.ContainsKey(key); + +#pragma warning disable CS8767 + public bool TryGetValue(string key, [NotNullWhen(true)] out string? value) + => this.parsedArgs.TryGetValue(key, out value); +#pragma warning restore CS8767 + + public IEnumerator> GetEnumerator() + => this.parsedArgs.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() + => this.GetEnumerator(); + + /// + /// “/key:value”形式の起動オプションを解釈し Dictionary に変換する + /// + /// + /// 不正な形式のオプションは除外されます。 + /// また、重複したキーのオプションが入力された場合は末尾に書かれたオプションが採用されます。 + /// + private Dictionary ParseArguments(string[] arguments) + { + var optionPattern = new Regex(@"^/(.+?)(?::(.*))?$"); + + return arguments.Select(x => optionPattern.Match(x)) + .Where(x => x.Success) + .GroupBy(x => x.Groups[1].Value) + .ToDictionary(x => x.Key, x => x.Last().Groups[2].Value); + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 57f7ca161..c660023a6 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -124,6 +124,7 @@ AuthDialog.cs + From 0db8fe8243e1b926bf68fcfcc72d9e575e46f3bb Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 3 Apr 2022 23:41:07 +0900 Subject: [PATCH 151/402] =?UTF-8?q?=E8=B5=B7=E5=8B=95=E8=A6=81=E4=BB=B6?= =?UTF-8?q?=E3=81=AE=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=82=92ApplicationPreconditions=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 63 +----------- OpenTween/ApplicationPreconditions.cs | 138 ++++++++++++++++++++++++++ OpenTween/OpenTween.csproj | 1 + 3 files changed, 140 insertions(+), 62 deletions(-) create mode 100644 OpenTween/ApplicationPreconditions.cs diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index d47232602..c4f13c937 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -32,10 +32,8 @@ using System.Globalization; using System.IO; using System.Linq; -using System.Security.Principal; using System.Threading; using System.Windows.Forms; -using Microsoft.Win32; using OpenTween.Setting; namespace OpenTween @@ -66,15 +64,8 @@ public static int Main(string[] args) StartupOptions = new(args); - WarnIfApiKeyError(); - WarnIfRunAsAdministrator(); - - if (!CheckRuntimeVersion()) - { - var message = string.Format(Properties.Resources.CheckRuntimeVersion_Error, ".NET Framework 4.7.2"); - MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error); + if (!ApplicationPreconditions.CheckAll()) return 1; - } if (!SetConfigDirectoryPath()) return 1; @@ -104,58 +95,6 @@ public static int Main(string[] args) return 0; } - private static void WarnIfApiKeyError() - { - var canDecrypt = ApplicationSettings.TwitterConsumerKey.TryGetValue(out _); - if (!canDecrypt) - { - var message = Properties.Resources.WarnIfApiKeyError_Message; - MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning); - Environment.Exit(-1); - } - } - - /// - /// OpenTween が管理者権限で実行されている場合に警告を表示します - /// - private static void WarnIfRunAsAdministrator() - { - // UAC が無効なシステムでは警告を表示しない - using var lmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32); - using var systemKey = lmKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\"); - - var enableLUA = (int?)systemKey?.GetValue("EnableLUA"); - if (enableLUA != 1) - return; - - using var currentIdentity = WindowsIdentity.GetCurrent(); - var principal = new WindowsPrincipal(currentIdentity); - if (principal.IsInRole(WindowsBuiltInRole.Administrator)) - { - var message = string.Format(Properties.Resources.WarnIfRunAsAdministrator_Message, ApplicationSettings.ApplicationName); - MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - } - - /// - /// 動作中の .NET Framework のバージョンが適切かチェックします - /// - private static bool CheckRuntimeVersion() - { - // Mono 上で動作している場合はバージョンチェックを無視します - if (Type.GetType("Mono.Runtime", false) != null) - return true; - - // .NET Framework 4.7.2 以降で動作しているかチェックする - // 参照: https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed - - using var lmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32); - using var ndpKey = lmKey.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"); - - var releaseKey = (int)ndpKey.GetValue("Release"); - return releaseKey >= 461808; - } - private static void TryActivatePreviousWindow() { // 実行中の同じアプリケーションのウィンドウ・ハンドルの取得 diff --git a/OpenTween/ApplicationPreconditions.cs b/OpenTween/ApplicationPreconditions.cs new file mode 100644 index 000000000..9e36bd838 --- /dev/null +++ b/OpenTween/ApplicationPreconditions.cs @@ -0,0 +1,138 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Security.Principal; +using System.Windows.Forms; +using Microsoft.Win32; + +namespace OpenTween +{ + /// + /// アプリケーションの起動要件を満たしているか確認するクラス + /// + public sealed class ApplicationPreconditions + { + // .NET Framework ランタイムの最小要件 + // 参照: https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed + private const string RuntimeMinimumVersionName = ".NET Framework 4.7.2"; + private const int RuntimeMinimumVersion = 461808; + + /// + /// 全ての起動要件を満たしているか確認する + /// + /// + /// 起動に必須な要件を全て満たしている場合は true、それ以外は false。 + /// + public static bool CheckAll() + { + var conditions = new ApplicationPreconditions(); + + if (!conditions.CheckApiKey()) + { + var message = Properties.Resources.WarnIfApiKeyError_Message; + ShowMessageBox(message, MessageBoxIcon.Error); + return false; + } + + if (!conditions.CheckRuntimeVersion()) + { + var message = string.Format(Properties.Resources.CheckRuntimeVersion_Error, RuntimeMinimumVersionName); + ShowMessageBox(message, MessageBoxIcon.Error); + return false; + } + + if (!conditions.CheckRunAsNormalUser()) + { + var message = string.Format(Properties.Resources.WarnIfRunAsAdministrator_Message, ApplicationSettings.ApplicationName); + ShowMessageBox(message, MessageBoxIcon.Warning); + } + + return true; + } + + private static void ShowMessageBox(string message, MessageBoxIcon icon) + => MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, icon); + + /// + /// API キーが復号できる状態であるか確認する + /// + public bool CheckApiKey() + => this.CanDecryptApiKey(ApplicationSettings.TwitterConsumerKey); + + /// + /// 動作中の .NET Framework のバージョンが適切か確認する + /// + public bool CheckRuntimeVersion() + { + // Mono 上で動作している場合は無視する + if (this.IsRunOnMono()) + return true; + + return this.GetFrameworkReleaseKey() >= RuntimeMinimumVersion; + } + + /// + /// プロセスが管理者権限で実行されていないか確認する + /// + public bool CheckRunAsNormalUser() + { + // UAC が無効なシステムでは警告を表示しない + if (!this.GetEnableLUA()) + return true; + + return !this.IsRunAsAdministrator(); + } + + private bool CanDecryptApiKey(ApiKey apiKey) + => apiKey.TryGetValue(out _); + + private bool IsRunOnMono() + => Type.GetType("Mono.Runtime", false) != null; + + private int GetFrameworkReleaseKey() + { + using var lmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32); + using var ndpKey = lmKey.OpenSubKey(@"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\"); + + return (int)ndpKey.GetValue("Release"); + } + + private bool GetEnableLUA() + { + using var lmKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32); + using var systemKey = lmKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\"); + + var enableLUA = (int?)systemKey?.GetValue("EnableLUA"); + return enableLUA == 1; + } + + private bool IsRunAsAdministrator() + { + using var currentIdentity = WindowsIdentity.GetCurrent(); + var principal = new WindowsPrincipal(currentIdentity); + + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index c660023a6..ce1491338 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -103,6 +103,7 @@ Code + From 4e69a8fa64877aec960190f58a8dc7e17b2c5f6f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 00:31:50 +0900 Subject: [PATCH 152/402] =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E3=82=B1?= =?UTF-8?q?=E3=83=BC=E3=82=B7=E3=83=A7=E3=83=B3=E3=81=AE=E5=A4=9A=E9=87=8D?= =?UTF-8?q?=E8=B5=B7=E5=8B=95=E3=81=AE=E6=8A=91=E5=88=B6=E5=87=A6=E7=90=86?= =?UTF-8?q?=E3=82=92ApplicationInstanceMutex=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApplicationInstanceMutexTest.cs | 48 +++++++++ OpenTween/ApplicationEvents.cs | 56 ++-------- OpenTween/ApplicationInstanceMutex.cs | 100 ++++++++++++++++++ OpenTween/OpenTween.csproj | 1 + 4 files changed, 159 insertions(+), 46 deletions(-) create mode 100644 OpenTween.Tests/ApplicationInstanceMutexTest.cs create mode 100644 OpenTween/ApplicationInstanceMutex.cs diff --git a/OpenTween.Tests/ApplicationInstanceMutexTest.cs b/OpenTween.Tests/ApplicationInstanceMutexTest.cs new file mode 100644 index 000000000..d6fb25cbf --- /dev/null +++ b/OpenTween.Tests/ApplicationInstanceMutexTest.cs @@ -0,0 +1,48 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using Xunit; + +namespace OpenTween +{ + public class ApplicationInstanceMutexTest + { + [Fact] + public void InstanceExists_SameNameTest() + { + using var mutex1 = new ApplicationInstanceMutex("OpenTweenTest", "."); + Assert.False(mutex1.InstanceExists); + + using var mutex2 = new ApplicationInstanceMutex("OpenTweenTest", "."); + Assert.True(mutex2.InstanceExists); + } + + [Fact] + public void InstanceExists_NotSameNameTest() + { + using var mutex1 = new ApplicationInstanceMutex("OpenTweenTest", "aaa"); + Assert.False(mutex1.InstanceExists); + + using var mutex2 = new ApplicationInstanceMutex("OpenTweenTest", "bbb"); + Assert.False(mutex2.InstanceExists); + } + } +} diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index c4f13c937..2d09eadb3 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -28,7 +28,6 @@ #nullable enable using System; -using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; @@ -73,57 +72,22 @@ public static int Main(string[] args) SettingManager.LoadAll(); InitCulture(); - { - // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する - var pt = MyCommon.SettingPath.Replace("\\", "/") + "/" + ApplicationSettings.AssemblyName; - using var mt = new Mutex(false, pt); - - if (!mt.WaitOne(0, false)) - { - var text = string.Format(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), ApplicationSettings.AssemblyName); - MessageBox.Show(text, MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information); - TryActivatePreviousWindow(); - return 1; - } - - Application.Run(new TweenMain()); + // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する + using var mutex = new ApplicationInstanceMutex(ApplicationSettings.AssemblyName, MyCommon.SettingPath); - mt.ReleaseMutex(); - } - - return 0; - } - - private static void TryActivatePreviousWindow() - { - // 実行中の同じアプリケーションのウィンドウ・ハンドルの取得 - var prevProcess = GetPreviousProcess(); - if (prevProcess == null) + if (mutex.InstanceExists) { - return; - } + var text = string.Format(MyCommon.ReplaceAppName(Properties.Resources.StartupText1), ApplicationSettings.AssemblyName); + MessageBox.Show(text, MyCommon.ReplaceAppName(Properties.Resources.StartupText2), MessageBoxButtons.OK, MessageBoxIcon.Information); - var windowHandle = NativeMethods.GetWindowHandle((uint)prevProcess.Id, ApplicationSettings.ApplicationName); - if (windowHandle != IntPtr.Zero) - { - NativeMethods.SetActiveWindow(windowHandle); + mutex.TryActivatePreviousInstance(); + return 1; } - } - private static Process? GetPreviousProcess() - { - var currentProcess = Process.GetCurrentProcess(); - try - { - return Process.GetProcessesByName(currentProcess.ProcessName) - .Where(p => p.Id != currentProcess.Id) - .FirstOrDefault(p => p.MainModule.FileName.Equals(currentProcess.MainModule.FileName, StringComparison.OrdinalIgnoreCase)); - } - catch - { - return null; - } + Application.Run(new TweenMain()); + + return 0; } public static void InitCulture() diff --git a/OpenTween/ApplicationInstanceMutex.cs b/OpenTween/ApplicationInstanceMutex.cs new file mode 100644 index 000000000..3a5bf655b --- /dev/null +++ b/OpenTween/ApplicationInstanceMutex.cs @@ -0,0 +1,100 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2007-2012 kiri_feather (@kiri_feather) +// (c) 2008-2012 Moz (@syo68k) +// (c) 2008-2012 takeshik (@takeshik) +// (c) 2010-2012 anis774 (@anis774) +// (c) 2010-2012 fantasticswallow (@f_swallow) +// (c) 2012 Egtra (@egtra) +// (c) 2012 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Diagnostics; +using System.Linq; +using System.Threading; + +namespace OpenTween +{ + /// + /// アプリケーションの多重起動を抑制するためのクラス + /// + public sealed class ApplicationInstanceMutex : IDisposable + { + public bool IsDisposed { get; private set; } = false; + + private readonly Mutex mutex; + private readonly bool createdNew; + + public ApplicationInstanceMutex(string appName, string settingPath) + { + var name = $"{settingPath.Replace(@"\", "/")}/{appName}"; + this.mutex = new Mutex(initiallyOwned: true, name, out this.createdNew); + } + + /// + /// 他のインスタンスが既に起動している場合は true、それ以外は false + /// + public bool InstanceExists + => !this.createdNew; + + public void TryActivatePreviousInstance() + { + // 実行中の同じアプリケーションのウィンドウ・ハンドルの取得 + var prevProcess = this.GetPreviousProcess(); + if (prevProcess == null) + return; + + var windowHandle = NativeMethods.GetWindowHandle((uint)prevProcess.Id, ApplicationSettings.ApplicationName); + if (windowHandle != IntPtr.Zero) + NativeMethods.SetActiveWindow(windowHandle); + } + + private Process? GetPreviousProcess() + { + try + { + var currentProcess = Process.GetCurrentProcess(); + + return Process.GetProcessesByName(currentProcess.ProcessName) + .Where(p => p.Id != currentProcess.Id) + .FirstOrDefault(p => p.MainModule.FileName.Equals(currentProcess.MainModule.FileName, StringComparison.OrdinalIgnoreCase)); + } + catch + { + return null; + } + } + + public void Dispose() + { + if (this.IsDisposed) + return; + + this.IsDisposed = true; + + if (this.createdNew) + this.mutex.ReleaseMutex(); + + this.mutex.Dispose(); + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index ce1491338..083a48af0 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -103,6 +103,7 @@ Code + From b6fa9037c8433d7d0141f78ddb1177ef9e1404db Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 02:00:04 +0900 Subject: [PATCH 153/402] =?UTF-8?q?UI=E3=82=AB=E3=83=AB=E3=83=81=E3=83=A3?= =?UTF-8?q?=E3=81=AE=E5=88=9D=E6=9C=9F=E5=8C=96=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?CultureService=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=88=86?= =?UTF-8?q?=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ionEventsTest.cs => CultureServiceTest.cs} | 4 +- OpenTween/ApplicationEvents.cs | 44 +---------- OpenTween/CultureService.cs | 79 +++++++++++++++++++ OpenTween/OpenTween.csproj | 1 + 4 files changed, 84 insertions(+), 44 deletions(-) rename OpenTween.Tests/{ApplicationEventsTest.cs => CultureServiceTest.cs} (92%) create mode 100644 OpenTween/CultureService.cs diff --git a/OpenTween.Tests/ApplicationEventsTest.cs b/OpenTween.Tests/CultureServiceTest.cs similarity index 92% rename from OpenTween.Tests/ApplicationEventsTest.cs rename to OpenTween.Tests/CultureServiceTest.cs index 8bf75c712..9844b551e 100644 --- a/OpenTween.Tests/ApplicationEventsTest.cs +++ b/OpenTween.Tests/CultureServiceTest.cs @@ -29,7 +29,7 @@ namespace OpenTween { - public class ApplicationEventsTest + public class CultureServiceTest { [Theory] [InlineData("ja-JP", "ja-JP")] @@ -38,7 +38,7 @@ public class ApplicationEventsTest [InlineData("zh-TW", "en")] public void GetPreferredCulture_Test(string currentCulture, string expectedCulture) { - var actual = ApplicationEvents.GetPreferredCulture(new CultureInfo(currentCulture)); + var actual = CultureService.GetPreferredCulture(new CultureInfo(currentCulture)); Assert.Equal(expectedCulture, actual.Name); } } diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 2d09eadb3..32e6ca73a 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -28,10 +28,7 @@ #nullable enable using System; -using System.Globalization; using System.IO; -using System.Linq; -using System.Threading; using System.Windows.Forms; using OpenTween.Setting; @@ -39,12 +36,6 @@ namespace OpenTween { internal class ApplicationEvents { - public static readonly CultureInfo[] SupportedUICulture = new[] - { - new CultureInfo("en"), // 先頭のカルチャはフォールバック先として使用される - new CultureInfo("ja"), - }; - /// /// 起動時に指定されたオプションを取得します /// @@ -71,7 +62,8 @@ public static int Main(string[] args) SettingManager.LoadAll(); - InitCulture(); + var cultureService = new CultureService(SettingManager.Common); + cultureService.Initialize(); // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する using var mutex = new ApplicationInstanceMutex(ApplicationSettings.AssemblyName, MyCommon.SettingPath); @@ -90,38 +82,6 @@ public static int Main(string[] args) return 0; } - public static void InitCulture() - { - var currentCulture = CultureInfo.CurrentUICulture; - - var settingCultureStr = SettingManager.Common.Language; - if (settingCultureStr != "OS") - { - try - { - currentCulture = new CultureInfo(settingCultureStr); - } - catch (CultureNotFoundException) - { - } - } - - var preferredCulture = GetPreferredCulture(currentCulture); - CultureInfo.DefaultThreadCurrentUICulture = preferredCulture; - Thread.CurrentThread.CurrentUICulture = preferredCulture; - } - - /// - /// サポートしているカルチャの中から、指定されたカルチャに対して適切なカルチャを選択して返します - /// - public static CultureInfo GetPreferredCulture(CultureInfo culture) - { - if (SupportedUICulture.Any(x => x.Contains(culture))) - return culture; - - return SupportedUICulture[0]; - } - private static bool SetConfigDirectoryPath() { if (StartupOptions.TryGetValue("configDir", out var configDir) && !MyCommon.IsNullOrEmpty(configDir)) diff --git a/OpenTween/CultureService.cs b/OpenTween/CultureService.cs new file mode 100644 index 000000000..50eee2b12 --- /dev/null +++ b/OpenTween/CultureService.cs @@ -0,0 +1,79 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2007-2012 kiri_feather (@kiri_feather) +// (c) 2008-2012 Moz (@syo68k) +// (c) 2008-2012 takeshik (@takeshik) +// (c) 2010-2012 anis774 (@anis774) +// (c) 2010-2012 fantasticswallow (@f_swallow) +// (c) 2012 Egtra (@egtra) +// (c) 2012 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System.Globalization; +using System.Linq; +using System.Threading; + +namespace OpenTween +{ + public class CultureService + { + public static readonly CultureInfo[] SupportedUICulture = new[] + { + new CultureInfo("en"), // 先頭のカルチャはフォールバック先として使用される + new CultureInfo("ja"), + }; + + private readonly SettingCommon settingCommon; + + public CultureService(SettingCommon settingCommon) + => this.settingCommon = settingCommon; + + public void Initialize() + { + var settingCultureStr = this.settingCommon.Language; + if (settingCultureStr == "OS") + return; + + try + { + var selectedCulture = new CultureInfo(settingCultureStr); + + var preferredCulture = GetPreferredCulture(selectedCulture); + CultureInfo.DefaultThreadCurrentUICulture = preferredCulture; + Thread.CurrentThread.CurrentUICulture = preferredCulture; + } + catch (CultureNotFoundException) + { + } + } + + /// + /// サポートしているカルチャの中から、指定されたカルチャに対して適切なカルチャを選択して返します + /// + public static CultureInfo GetPreferredCulture(CultureInfo culture) + { + if (SupportedUICulture.Any(x => x.Contains(culture))) + return culture; + + return SupportedUICulture[0]; + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 083a48af0..7364c29fd 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -128,6 +128,7 @@ + From 26beb17455bbb8dfa46c48603e1621b2bcf25904 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 07:11:29 +0900 Subject: [PATCH 154/402] =?UTF-8?q?SettingManager=E3=82=92Singleton?= =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TestUtils.cs | 16 +- OpenTween.Tests/TwitterTest.cs | 44 +- OpenTween/ApplicationEvents.cs | 12 +- OpenTween/MediaUploadServices/TwitterPhoto.cs | 2 +- OpenTween/Models/DirectMessagesTabModel.cs | 4 +- OpenTween/Models/FavoritesTabModel.cs | 4 +- OpenTween/Models/HomeTabModel.cs | 6 +- OpenTween/Models/ListTimelineTabModel.cs | 4 +- OpenTween/Models/MentionsTabModel.cs | 4 +- OpenTween/Models/PublicSearchTabModel.cs | 4 +- OpenTween/Models/RelatedPostsTabModel.cs | 4 +- OpenTween/Models/TabInformations.cs | 2 +- OpenTween/Models/TabModel.cs | 4 +- OpenTween/Models/UserTimelineTabModel.cs | 4 +- OpenTween/MyCommon.cs | 4 +- OpenTween/Setting/SettingManager.cs | 64 +- OpenTween/Thumbnail/MapThumb.cs | 2 +- OpenTween/Thumbnail/MapThumbGoogle.cs | 8 +- OpenTween/Thumbnail/MapThumbOSM.cs | 6 +- OpenTween/Tween.cs | 865 +++++++++--------- OpenTween/TweetDetailsView.cs | 18 +- OpenTween/TweetFormatter.cs | 2 +- OpenTween/Twitter.cs | 34 +- 23 files changed, 560 insertions(+), 557 deletions(-) diff --git a/OpenTween.Tests/TestUtils.cs b/OpenTween.Tests/TestUtils.cs index 1de865cc7..d7e2fb227 100644 --- a/OpenTween.Tests/TestUtils.cs +++ b/OpenTween.Tests/TestUtils.cs @@ -160,26 +160,26 @@ public class SettingManagerTest { public static SettingCommon Common { - get => SettingManager.Common; - set => SettingManager.Common = value; + get => SettingManager.Instance.Common; + set => SettingManager.Instance.Common = value; } public static SettingLocal Local { - get => SettingManager.Local; - set => SettingManager.Local = value; + get => SettingManager.Instance.Local; + set => SettingManager.Instance.Local = value; } public static SettingTabs Tabs { - get => SettingManager.Tabs; - set => SettingManager.Tabs = value; + get => SettingManager.Instance.Tabs; + set => SettingManager.Instance.Tabs = value; } public static SettingAtIdList AtIdList { - get => SettingManager.AtIdList; - set => SettingManager.AtIdList = value; + get => SettingManager.Instance.AtIdList; + set => SettingManager.Instance.AtIdList = value; } } } diff --git a/OpenTween.Tests/TwitterTest.cs b/OpenTween.Tests/TwitterTest.cs index 5fac92890..7da053a43 100644 --- a/OpenTween.Tests/TwitterTest.cs +++ b/OpenTween.Tests/TwitterTest.cs @@ -432,17 +432,17 @@ public void GetApiResultCount_DefaultTest() var oldInstance = SettingManagerTest.Common; SettingManagerTest.Common = new SettingCommon(); - var timeline = SettingManager.Common.CountApi; - var reply = SettingManager.Common.CountApiReply; - var more = SettingManager.Common.MoreCountApi; - var startup = SettingManager.Common.FirstCountApi; - var favorite = SettingManager.Common.FavoritesCountApi; - var list = SettingManager.Common.ListCountApi; - var search = SettingManager.Common.SearchCountApi; - var usertl = SettingManager.Common.UserTimelineCountApi; + var timeline = SettingManager.Instance.Common.CountApi; + var reply = SettingManager.Instance.Common.CountApiReply; + var more = SettingManager.Instance.Common.MoreCountApi; + var startup = SettingManager.Instance.Common.FirstCountApi; + var favorite = SettingManager.Instance.Common.FavoritesCountApi; + var list = SettingManager.Instance.Common.ListCountApi; + var search = SettingManager.Instance.Common.SearchCountApi; + var usertl = SettingManager.Instance.Common.UserTimelineCountApi; // デフォルト値チェック - Assert.False(SettingManager.Common.UseAdditionalCount); + Assert.False(SettingManager.Instance.Common.UseAdditionalCount); Assert.Equal(60, timeline); Assert.Equal(40, reply); Assert.Equal(200, more); @@ -471,16 +471,16 @@ public void GetApiResultCount_AdditionalCountTest() var oldInstance = SettingManagerTest.Common; SettingManagerTest.Common = new SettingCommon(); - var timeline = SettingManager.Common.CountApi; - var reply = SettingManager.Common.CountApiReply; - var more = SettingManager.Common.MoreCountApi; - var startup = SettingManager.Common.FirstCountApi; - var favorite = SettingManager.Common.FavoritesCountApi; - var list = SettingManager.Common.ListCountApi; - var search = SettingManager.Common.SearchCountApi; - var usertl = SettingManager.Common.UserTimelineCountApi; + var timeline = SettingManager.Instance.Common.CountApi; + var reply = SettingManager.Instance.Common.CountApiReply; + var more = SettingManager.Instance.Common.MoreCountApi; + var startup = SettingManager.Instance.Common.FirstCountApi; + var favorite = SettingManager.Instance.Common.FavoritesCountApi; + var list = SettingManager.Instance.Common.ListCountApi; + var search = SettingManager.Instance.Common.SearchCountApi; + var usertl = SettingManager.Instance.Common.UserTimelineCountApi; - SettingManager.Common.UseAdditionalCount = true; + SettingManager.Instance.Common.UseAdditionalCount = true; // Timeline Assert.Equal(timeline, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Timeline, false, false)); @@ -497,7 +497,7 @@ public void GetApiResultCount_AdditionalCountTest() Assert.Equal(favorite, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Favorites, true, false)); Assert.Equal(favorite, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Favorites, false, true)); - SettingManager.Common.FavoritesCountApi = 0; + SettingManager.Instance.Common.FavoritesCountApi = 0; Assert.Equal(timeline, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Favorites, false, false)); Assert.Equal(more, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Favorites, true, false)); @@ -508,7 +508,7 @@ public void GetApiResultCount_AdditionalCountTest() Assert.Equal(list, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.List, true, false)); Assert.Equal(list, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.List, false, true)); - SettingManager.Common.ListCountApi = 0; + SettingManager.Instance.Common.ListCountApi = 0; Assert.Equal(timeline, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.List, false, false)); Assert.Equal(more, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.List, true, false)); @@ -519,7 +519,7 @@ public void GetApiResultCount_AdditionalCountTest() Assert.Equal(search, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.PublicSearch, true, false)); Assert.Equal(search, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.PublicSearch, false, true)); - SettingManager.Common.SearchCountApi = 0; + SettingManager.Instance.Common.SearchCountApi = 0; Assert.Equal(timeline, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.PublicSearch, false, false)); Assert.Equal(search, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.PublicSearch, true, false)); // MoreCountApiの値がPublicSearchの最大値に制限される @@ -530,7 +530,7 @@ public void GetApiResultCount_AdditionalCountTest() Assert.Equal(usertl, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.UserTimeline, true, false)); Assert.Equal(usertl, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.UserTimeline, false, true)); - SettingManager.Common.UserTimelineCountApi = 0; + SettingManager.Instance.Common.UserTimelineCountApi = 0; Assert.Equal(timeline, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.UserTimeline, false, false)); Assert.Equal(more, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.UserTimeline, true, false)); diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 32e6ca73a..81d31566e 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -60,9 +60,9 @@ public static int Main(string[] args) if (!SetConfigDirectoryPath()) return 1; - SettingManager.LoadAll(); + SettingManager.Instance.LoadAll(); - var cultureService = new CultureService(SettingManager.Common); + var cultureService = new CultureService(SettingManager.Instance.Common); cultureService.Initialize(); // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する @@ -101,12 +101,12 @@ private static bool SetConfigDirectoryPath() // OpenTween.exe と同じディレクトリに設定ファイルを配置する MyCommon.SettingPath = Application.StartupPath; - SettingManager.LoadAll(); + SettingManager.Instance.LoadAll(); try { // 設定ファイルが書き込み可能な状態であるかテストする - SettingManager.SaveAll(); + SettingManager.Instance.SaveAll(); } catch (UnauthorizedAccessException) { @@ -150,7 +150,7 @@ private static bool SetConfigDirectoryPath() { // 既に Roaming に設定ファイルが存在し、Roaming 内のファイルの方が新しい場合は // StartupPath に設定ファイルが存在しても無視する - SettingManager.LoadAll(); + SettingManager.Instance.LoadAll(); } else { @@ -162,7 +162,7 @@ private static bool SetConfigDirectoryPath() } // Roaming に設定ファイルを作成 (StartupPath に読み込みに成功した設定ファイルがあれば内容がコピーされる) - SettingManager.SaveAll(); + SettingManager.Instance.SaveAll(); } } } diff --git a/OpenTween/MediaUploadServices/TwitterPhoto.cs b/OpenTween/MediaUploadServices/TwitterPhoto.cs index 5356f7be8..4929d84c0 100644 --- a/OpenTween/MediaUploadServices/TwitterPhoto.cs +++ b/OpenTween/MediaUploadServices/TwitterPhoto.cs @@ -153,7 +153,7 @@ await this.tw.Api.MediaMetadataCreate(mediaId, media.AltText) using var origImage = mediaItem.CreateImage(); - if (SettingManager.Common.AlphaPNGWorkaround && this.AddAlphaChannelIfNeeded(origImage.Image, out var newImage)) + if (SettingManager.Instance.Common.AlphaPNGWorkaround && this.AddAlphaChannelIfNeeded(origImage.Image, out var newImage)) { using var newMediaItem = new MemoryImageMediaItem(newImage!); newMediaItem.AltText = mediaItem.AltText; diff --git a/OpenTween/Models/DirectMessagesTabModel.cs b/OpenTween/Models/DirectMessagesTabModel.cs index 725b636fb..d3a957394 100644 --- a/OpenTween/Models/DirectMessagesTabModel.cs +++ b/OpenTween/Models/DirectMessagesTabModel.cs @@ -54,10 +54,10 @@ public DirectMessagesTabModel(string tabName) public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress) { bool read; - if (!SettingManager.Common.UnreadManage) + if (!SettingManager.Instance.Common.UnreadManage) read = true; else - read = startup && SettingManager.Common.Read; + read = startup && SettingManager.Instance.Common.Read; progress.Report(string.Format(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText8, backward ? -1 : 1)); diff --git a/OpenTween/Models/FavoritesTabModel.cs b/OpenTween/Models/FavoritesTabModel.cs index 06897d74e..40d348fa5 100644 --- a/OpenTween/Models/FavoritesTabModel.cs +++ b/OpenTween/Models/FavoritesTabModel.cs @@ -54,10 +54,10 @@ public FavoritesTabModel(string tabName) public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress) { bool read; - if (!SettingManager.Common.UnreadManage) + if (!SettingManager.Instance.Common.UnreadManage) read = true; else - read = startup && SettingManager.Common.Read; + read = startup && SettingManager.Instance.Common.Read; progress.Report(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText19); diff --git a/OpenTween/Models/HomeTabModel.cs b/OpenTween/Models/HomeTabModel.cs index 41aaa1547..4bbc880f0 100644 --- a/OpenTween/Models/HomeTabModel.cs +++ b/OpenTween/Models/HomeTabModel.cs @@ -68,10 +68,10 @@ public override void AddPostQueue(PostClass post) public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress) { bool read; - if (!SettingManager.Common.UnreadManage) + if (!SettingManager.Instance.Common.UnreadManage) read = true; else - read = startup && SettingManager.Common.Read; + read = startup && SettingManager.Instance.Common.Read; progress.Report(string.Format(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText5, backward ? -1 : 1)); @@ -79,7 +79,7 @@ await tw.GetHomeTimelineApi(read, this, backward, startup) .ConfigureAwait(false); // 新着時未読クリア - if (SettingManager.Common.ReadOldPosts) + if (SettingManager.Instance.Common.ReadOldPosts) TabInformations.GetInstance().SetReadHomeTab(); TabInformations.GetInstance().DistributePosts(); diff --git a/OpenTween/Models/ListTimelineTabModel.cs b/OpenTween/Models/ListTimelineTabModel.cs index 6769bc73f..fcdae9ace 100644 --- a/OpenTween/Models/ListTimelineTabModel.cs +++ b/OpenTween/Models/ListTimelineTabModel.cs @@ -55,10 +55,10 @@ public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, return; bool read; - if (!SettingManager.Common.UnreadManage) + if (!SettingManager.Instance.Common.UnreadManage) read = true; else - read = startup && SettingManager.Common.Read; + read = startup && SettingManager.Instance.Common.Read; progress.Report("List refreshing..."); diff --git a/OpenTween/Models/MentionsTabModel.cs b/OpenTween/Models/MentionsTabModel.cs index a705b9de2..508fb6c01 100644 --- a/OpenTween/Models/MentionsTabModel.cs +++ b/OpenTween/Models/MentionsTabModel.cs @@ -54,10 +54,10 @@ public MentionsTabModel(string tabName) public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress) { bool read; - if (!SettingManager.Common.UnreadManage) + if (!SettingManager.Instance.Common.UnreadManage) read = true; else - read = startup && SettingManager.Common.Read; + read = startup && SettingManager.Instance.Common.Read; progress.Report(string.Format(Properties.Resources.GetTimelineWorker_RunWorkerCompletedText4, backward ? -1 : 1)); diff --git a/OpenTween/Models/PublicSearchTabModel.cs b/OpenTween/Models/PublicSearchTabModel.cs index d3baa449e..43c6ade10 100644 --- a/OpenTween/Models/PublicSearchTabModel.cs +++ b/OpenTween/Models/PublicSearchTabModel.cs @@ -75,10 +75,10 @@ public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, return; bool read; - if (!SettingManager.Common.UnreadManage) + if (!SettingManager.Instance.Common.UnreadManage) read = true; else - read = startup && SettingManager.Common.Read; + read = startup && SettingManager.Instance.Common.Read; progress.Report("Search refreshing..."); diff --git a/OpenTween/Models/RelatedPostsTabModel.cs b/OpenTween/Models/RelatedPostsTabModel.cs index 36b646bf5..9f46cd5bd 100644 --- a/OpenTween/Models/RelatedPostsTabModel.cs +++ b/OpenTween/Models/RelatedPostsTabModel.cs @@ -57,10 +57,10 @@ public Task RefreshAsync(Twitter tw, bool startup, IProgress progress) public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, IProgress progress) { bool read; - if (!SettingManager.Common.UnreadManage) + if (!SettingManager.Instance.Common.UnreadManage) read = true; else - read = startup && SettingManager.Common.Read; + read = startup && SettingManager.Instance.Common.Read; try { diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index 085047fee..a35dc4e90 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -522,7 +522,7 @@ public void AddPost(PostClass item) if (item.IsFav && item.RetweetedId != null) item.IsFav = false; // 既に持っている公式RTは捨てる - if (item.RetweetedId != null && SettingManager.Common.HideDuplicatedRetweets) + if (item.RetweetedId != null && SettingManager.Instance.Common.HideDuplicatedRetweets) { var retweetCount = this.UpdateRetweetCount(item); diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index e546e5956..fde2cfe6b 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -266,7 +266,7 @@ public long NextUnreadId { get { - if (!this.UnreadManage || !SettingManager.Common.UnreadManage) + if (!this.UnreadManage || !SettingManager.Instance.Common.UnreadManage) return -1L; if (this.unreadIds.Count == 0) @@ -299,7 +299,7 @@ public int UnreadCount { get { - if (!this.UnreadManage || !SettingManager.Common.UnreadManage) + if (!this.UnreadManage || !SettingManager.Instance.Common.UnreadManage) return 0; return this.unreadIds.Count; diff --git a/OpenTween/Models/UserTimelineTabModel.cs b/OpenTween/Models/UserTimelineTabModel.cs index 07110ca8a..05329f8c5 100644 --- a/OpenTween/Models/UserTimelineTabModel.cs +++ b/OpenTween/Models/UserTimelineTabModel.cs @@ -55,10 +55,10 @@ public override async Task RefreshAsync(Twitter tw, bool backward, bool startup, return; bool read; - if (!SettingManager.Common.UnreadManage) + if (!SettingManager.Instance.Common.UnreadManage) read = true; else - read = startup && SettingManager.Common.Read; + read = startup && SettingManager.Instance.Common.Read; progress.Report("UserTimeline refreshing..."); diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 3c7f5ba49..8336118f1 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -391,7 +391,7 @@ public static bool ExceptionOut(Exception ex) writer.Write(errorReport); } - var settings = SettingManager.Common; + var settings = SettingManager.Instance.Common; var mainForm = Application.OpenForms.OfType().FirstOrDefault(); ErrorReport report; @@ -987,7 +987,7 @@ public static bool IsNullOrEmpty([NotNullWhen(false)] string? value) => string.IsNullOrEmpty(value); public static Task OpenInBrowserAsync(IWin32Window? owner, string url) - => MyCommon.OpenInBrowserAsync(owner, SettingManager.Local.BrowserPath, url); + => MyCommon.OpenInBrowserAsync(owner, SettingManager.Instance.Local.BrowserPath, url); public static Task OpenInBrowserAsync(IWin32Window? owner, string? browserPath, string url) { diff --git a/OpenTween/Setting/SettingManager.cs b/OpenTween/Setting/SettingManager.cs index 9dd114146..0ae80f7c9 100644 --- a/OpenTween/Setting/SettingManager.cs +++ b/OpenTween/Setting/SettingManager.cs @@ -29,25 +29,27 @@ namespace OpenTween.Setting { - public static class SettingManager + public class SettingManager { - public static SettingCommon Common { get; internal set; } = new(); + public static SettingManager Instance { get; } = new(); - public static SettingLocal Local { get; internal set; } = new(); + public SettingCommon Common { get; internal set; } = new(); - public static SettingTabs Tabs { get; internal set; } = new(); + public SettingLocal Local { get; internal set; } = new(); - public static SettingAtIdList AtIdList { get; internal set; } = new(); + public SettingTabs Tabs { get; internal set; } = new(); - public static void LoadAll() + public SettingAtIdList AtIdList { get; internal set; } = new(); + + public void LoadAll() { - LoadCommon(); - LoadLocal(); - LoadTabs(); - LoadAtIdList(); + this.LoadCommon(); + this.LoadLocal(); + this.LoadTabs(); + this.LoadAtIdList(); } - public static void LoadCommon() + public void LoadCommon() { var settings = SettingCommon.Load(); @@ -68,36 +70,36 @@ public static void LoadCommon() } } - SettingManager.Common = settings; + this.Common = settings; } - public static void LoadLocal() - => SettingManager.Local = SettingLocal.Load(); + public void LoadLocal() + => this.Local = SettingLocal.Load(); - public static void LoadTabs() - => SettingManager.Tabs = SettingTabs.Load(); + public void LoadTabs() + => this.Tabs = SettingTabs.Load(); - public static void LoadAtIdList() - => SettingManager.AtIdList = SettingAtIdList.Load(); + public void LoadAtIdList() + => this.AtIdList = SettingAtIdList.Load(); - public static void SaveAll() + public void SaveAll() { - SaveCommon(); - SaveLocal(); - SaveTabs(); - SaveAtIdList(); + this.SaveCommon(); + this.SaveLocal(); + this.SaveTabs(); + this.SaveAtIdList(); } - public static void SaveCommon() - => SettingManager.Common.Save(); + public void SaveCommon() + => this.Common.Save(); - public static void SaveLocal() - => SettingManager.Local.Save(); + public void SaveLocal() + => this.Local.Save(); - public static void SaveTabs() - => SettingManager.Tabs.Save(); + public void SaveTabs() + => this.Tabs.Save(); - public static void SaveAtIdList() - => SettingManager.AtIdList.Save(); + public void SaveAtIdList() + => this.AtIdList.Save(); } } diff --git a/OpenTween/Thumbnail/MapThumb.cs b/OpenTween/Thumbnail/MapThumb.cs index e4c558edf..cd60ceaed 100644 --- a/OpenTween/Thumbnail/MapThumb.cs +++ b/OpenTween/Thumbnail/MapThumb.cs @@ -40,7 +40,7 @@ public abstract class MapThumb public static MapThumb GetDefaultInstance() { - var confValue = SettingManager.Common.MapThumbnailProvider; + var confValue = SettingManager.Instance.Common.MapThumbnailProvider; var classType = confValue switch { MapProvider.OpenStreetMap => typeof(MapThumbOSM), diff --git a/OpenTween/Thumbnail/MapThumbGoogle.cs b/OpenTween/Thumbnail/MapThumbGoogle.cs index 622ed7d4a..11a393412 100644 --- a/OpenTween/Thumbnail/MapThumbGoogle.cs +++ b/OpenTween/Thumbnail/MapThumbGoogle.cs @@ -48,9 +48,9 @@ public override Task GetThumbnailInfoAsync(PostClass.StatusGeo ge public string CreateStaticMapUrl(double latitude, double longitude) { - var width = SettingManager.Common.MapThumbnailWidth; // この辺なんとかならんかなあ - var height = SettingManager.Common.MapThumbnailHeight; - var zoom = SettingManager.Common.MapThumbnailZoom; + var width = SettingManager.Instance.Common.MapThumbnailWidth; // この辺なんとかならんかなあ + var height = SettingManager.Instance.Common.MapThumbnailHeight; + var zoom = SettingManager.Instance.Common.MapThumbnailZoom; var location = latitude + "," + longitude; var baseUrl = "https://maps.googleapis.com/maps/api/staticmap"; @@ -60,7 +60,7 @@ public string CreateStaticMapUrl(double latitude, double longitude) public string CreateMapLinkUrl(double latitude, double longitude) { - var zoom = SettingManager.Common.MapThumbnailZoom; + var zoom = SettingManager.Instance.Common.MapThumbnailZoom; var location = latitude + "," + longitude; var baseUrl = "https://maps.google.co.jp/maps"; diff --git a/OpenTween/Thumbnail/MapThumbOSM.cs b/OpenTween/Thumbnail/MapThumbOSM.cs index a9216ef17..e0a979b74 100644 --- a/OpenTween/Thumbnail/MapThumbOSM.cs +++ b/OpenTween/Thumbnail/MapThumbOSM.cs @@ -38,8 +38,8 @@ public class MapThumbOSM : MapThumb { public override Task GetThumbnailInfoAsync(PostClass.StatusGeo geo) { - var size = new Size(SettingManager.Common.MapThumbnailWidth, SettingManager.Common.MapThumbnailHeight); - var zoom = SettingManager.Common.MapThumbnailZoom; + var size = new Size(SettingManager.Instance.Common.MapThumbnailWidth, SettingManager.Instance.Common.MapThumbnailHeight); + var zoom = SettingManager.Instance.Common.MapThumbnailZoom; var thumb = new OSMThumbnailInfo(geo.Latitude, geo.Longitude, zoom, size) { @@ -51,7 +51,7 @@ public override Task GetThumbnailInfoAsync(PostClass.StatusGeo ge public string CreateMapLinkUrl(double latitude, double longitude) { - var zoom = SettingManager.Common.MapThumbnailZoom; + var zoom = SettingManager.Instance.Common.MapThumbnailZoom; return $"https://www.openstreetmap.org/?mlat={latitude}&mlon={longitude}#map={zoom}/{latitude}/{longitude}"; } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 1bcf361bf..566156dc3 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -132,6 +132,9 @@ public partial class TweenMain : OTBaseForm private bool soundfileListup = false; private FormWindowState formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する + // 設定ファイル + private readonly SettingManager settings = SettingManager.Instance; + // twitter解析部 private readonly TwitterApi twitterApi = new(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); private Twitter tw = null!; @@ -595,10 +598,10 @@ private void InitColumns(ListView list, bool startup) if (startup) { - var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / SettingManager.Local.ScaleDimension.Width; + var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / this.settings.Local.ScaleDimension.Width; - columns[0].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width1); - columns[1].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width3); + columns[0].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width1); + columns[1].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width3); columns[0].DisplayIndex = 0; columns[1].DisplayIndex = 1; } @@ -632,23 +635,23 @@ private void InitColumns(ListView list, bool startup) if (startup) { - var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / SettingManager.Local.ScaleDimension.Width; + var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / this.settings.Local.ScaleDimension.Width; - columns[0].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width1); - columns[1].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width2); - columns[2].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width3); - columns[3].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width4); - columns[4].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width5); - columns[5].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width6); - columns[6].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width7); - columns[7].Width = ScaleBy(widthScaleFactor, SettingManager.Local.Width8); + columns[0].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width1); + columns[1].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width2); + columns[2].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width3); + columns[3].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width4); + columns[4].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width5); + columns[5].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width6); + columns[6].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width7); + columns[7].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width8); var displayIndex = new[] { - SettingManager.Local.DisplayIndex1, SettingManager.Local.DisplayIndex2, - SettingManager.Local.DisplayIndex3, SettingManager.Local.DisplayIndex4, - SettingManager.Local.DisplayIndex5, SettingManager.Local.DisplayIndex6, - SettingManager.Local.DisplayIndex7, SettingManager.Local.DisplayIndex8, + this.settings.Local.DisplayIndex1, this.settings.Local.DisplayIndex2, + this.settings.Local.DisplayIndex3, this.settings.Local.DisplayIndex4, + this.settings.Local.DisplayIndex5, this.settings.Local.DisplayIndex6, + this.settings.Local.DisplayIndex7, this.settings.Local.DisplayIndex8, }; foreach (var i in Enumerable.Range(0, displayIndex.Length)) @@ -781,10 +784,10 @@ private void TweenMain_Load(object sender, EventArgs e) this.LoadConfig(); // 現在の DPI と設定保存時の DPI との比を取得する - var configScaleFactor = SettingManager.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions); + var configScaleFactor = this.settings.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions); // UIフォント設定 - var fontUIGlobal = SettingManager.Local.FontUIGlobal; + var fontUIGlobal = this.settings.Local.FontUIGlobal; if (fontUIGlobal != null) { OTBaseForm.GlobalFont = fontUIGlobal; @@ -794,54 +797,54 @@ private void TweenMain_Load(object sender, EventArgs e) // 不正値チェック if (!ApplicationEvents.StartupOptions.ContainsKey("nolimit")) { - if (SettingManager.Common.TimelinePeriod < 15 && SettingManager.Common.TimelinePeriod > 0) - SettingManager.Common.TimelinePeriod = 15; + if (this.settings.Common.TimelinePeriod < 15 && this.settings.Common.TimelinePeriod > 0) + this.settings.Common.TimelinePeriod = 15; - if (SettingManager.Common.ReplyPeriod < 15 && SettingManager.Common.ReplyPeriod > 0) - SettingManager.Common.ReplyPeriod = 15; + if (this.settings.Common.ReplyPeriod < 15 && this.settings.Common.ReplyPeriod > 0) + this.settings.Common.ReplyPeriod = 15; - if (SettingManager.Common.DMPeriod < 15 && SettingManager.Common.DMPeriod > 0) - SettingManager.Common.DMPeriod = 15; + if (this.settings.Common.DMPeriod < 15 && this.settings.Common.DMPeriod > 0) + this.settings.Common.DMPeriod = 15; - if (SettingManager.Common.PubSearchPeriod < 30 && SettingManager.Common.PubSearchPeriod > 0) - SettingManager.Common.PubSearchPeriod = 30; + if (this.settings.Common.PubSearchPeriod < 30 && this.settings.Common.PubSearchPeriod > 0) + this.settings.Common.PubSearchPeriod = 30; - if (SettingManager.Common.UserTimelinePeriod < 15 && SettingManager.Common.UserTimelinePeriod > 0) - SettingManager.Common.UserTimelinePeriod = 15; + if (this.settings.Common.UserTimelinePeriod < 15 && this.settings.Common.UserTimelinePeriod > 0) + this.settings.Common.UserTimelinePeriod = 15; - if (SettingManager.Common.ListsPeriod < 15 && SettingManager.Common.ListsPeriod > 0) - SettingManager.Common.ListsPeriod = 15; + if (this.settings.Common.ListsPeriod < 15 && this.settings.Common.ListsPeriod > 0) + this.settings.Common.ListsPeriod = 15; } - if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Timeline, SettingManager.Common.CountApi)) - SettingManager.Common.CountApi = 60; - if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Reply, SettingManager.Common.CountApiReply)) - SettingManager.Common.CountApiReply = 40; + if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Timeline, this.settings.Common.CountApi)) + this.settings.Common.CountApi = 60; + if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Reply, this.settings.Common.CountApiReply)) + this.settings.Common.CountApiReply = 40; - if (SettingManager.Common.MoreCountApi != 0 && !Twitter.VerifyMoreApiResultCount(SettingManager.Common.MoreCountApi)) - SettingManager.Common.MoreCountApi = 200; - if (SettingManager.Common.FirstCountApi != 0 && !Twitter.VerifyFirstApiResultCount(SettingManager.Common.FirstCountApi)) - SettingManager.Common.FirstCountApi = 100; + if (this.settings.Common.MoreCountApi != 0 && !Twitter.VerifyMoreApiResultCount(this.settings.Common.MoreCountApi)) + this.settings.Common.MoreCountApi = 200; + if (this.settings.Common.FirstCountApi != 0 && !Twitter.VerifyFirstApiResultCount(this.settings.Common.FirstCountApi)) + this.settings.Common.FirstCountApi = 100; - if (SettingManager.Common.FavoritesCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Favorites, SettingManager.Common.FavoritesCountApi)) - SettingManager.Common.FavoritesCountApi = 40; - if (SettingManager.Common.ListCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.List, SettingManager.Common.ListCountApi)) - SettingManager.Common.ListCountApi = 100; - if (SettingManager.Common.SearchCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.PublicSearch, SettingManager.Common.SearchCountApi)) - SettingManager.Common.SearchCountApi = 100; - if (SettingManager.Common.UserTimelineCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.UserTimeline, SettingManager.Common.UserTimelineCountApi)) - SettingManager.Common.UserTimelineCountApi = 20; + if (this.settings.Common.FavoritesCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Favorites, this.settings.Common.FavoritesCountApi)) + this.settings.Common.FavoritesCountApi = 40; + if (this.settings.Common.ListCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.List, this.settings.Common.ListCountApi)) + this.settings.Common.ListCountApi = 100; + if (this.settings.Common.SearchCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.PublicSearch, this.settings.Common.SearchCountApi)) + this.settings.Common.SearchCountApi = 100; + if (this.settings.Common.UserTimelineCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.UserTimeline, this.settings.Common.UserTimelineCountApi)) + this.settings.Common.UserTimelineCountApi = 20; // 廃止サービスが選択されていた場合ux.nuへ読み替え - if (SettingManager.Common.AutoShortUrlFirst < 0) - SettingManager.Common.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu; + if (this.settings.Common.AutoShortUrlFirst < 0) + this.settings.Common.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu; - TwitterApiConnection.RestApiHost = SettingManager.Common.TwitterApiHost; + TwitterApiConnection.RestApiHost = this.settings.Common.TwitterApiHost; this.tw = new Twitter(this.twitterApi); // 認証関連 - if (MyCommon.IsNullOrEmpty(SettingManager.Common.Token)) SettingManager.Common.UserName = ""; - this.tw.Initialize(SettingManager.Common.Token, SettingManager.Common.TokenSecret, SettingManager.Common.UserName, SettingManager.Common.UserId); + if (MyCommon.IsNullOrEmpty(this.settings.Common.Token)) this.settings.Common.UserName = ""; + this.tw.Initialize(this.settings.Common.Token, this.settings.Common.TokenSecret, this.settings.Common.UserName, this.settings.Common.UserId); this.initial = true; @@ -866,23 +869,23 @@ private void TweenMain_Load(object sender, EventArgs e) } // Twitter用通信クラス初期化 - Networking.DefaultTimeout = TimeSpan.FromSeconds(SettingManager.Common.DefaultTimeOut); - Networking.UploadImageTimeout = TimeSpan.FromSeconds(SettingManager.Common.UploadImageTimeout); + Networking.DefaultTimeout = TimeSpan.FromSeconds(this.settings.Common.DefaultTimeOut); + Networking.UploadImageTimeout = TimeSpan.FromSeconds(this.settings.Common.UploadImageTimeout); Networking.SetWebProxy( - SettingManager.Local.ProxyType, - SettingManager.Local.ProxyAddress, - SettingManager.Local.ProxyPort, - SettingManager.Local.ProxyUser, - SettingManager.Local.ProxyPassword); - Networking.ForceIPv4 = SettingManager.Common.ForceIPv4; - - TwitterApiConnection.RestApiHost = SettingManager.Common.TwitterApiHost; - this.tw.RestrictFavCheck = SettingManager.Common.RestrictFavCheck; - this.tw.ReadOwnPost = SettingManager.Common.ReadOwnPost; - ShortUrl.Instance.DisableExpanding = !SettingManager.Common.TinyUrlResolve; - ShortUrl.Instance.BitlyAccessToken = SettingManager.Common.BitlyAccessToken; - ShortUrl.Instance.BitlyId = SettingManager.Common.BilyUser; - ShortUrl.Instance.BitlyKey = SettingManager.Common.BitlyPwd; + this.settings.Local.ProxyType, + this.settings.Local.ProxyAddress, + this.settings.Local.ProxyPort, + this.settings.Local.ProxyUser, + this.settings.Local.ProxyPassword); + Networking.ForceIPv4 = this.settings.Common.ForceIPv4; + + TwitterApiConnection.RestApiHost = this.settings.Common.TwitterApiHost; + this.tw.RestrictFavCheck = this.settings.Common.RestrictFavCheck; + this.tw.ReadOwnPost = this.settings.Common.ReadOwnPost; + ShortUrl.Instance.DisableExpanding = !this.settings.Common.TinyUrlResolve; + ShortUrl.Instance.BitlyAccessToken = this.settings.Common.BitlyAccessToken; + ShortUrl.Instance.BitlyId = this.settings.Common.BilyUser; + ShortUrl.Instance.BitlyKey = this.settings.Common.BitlyPwd; // アクセストークンが有効であるか確認する // ここが Twitter API への最初のアクセスになるようにすること @@ -905,23 +908,23 @@ private void TweenMain_Load(object sender, EventArgs e) ThumbnailGenerator.InitializeGenerator(); var imgazyobizinet = ThumbnailGenerator.ImgAzyobuziNetInstance; - imgazyobizinet.Enabled = SettingManager.Common.EnableImgAzyobuziNet; - imgazyobizinet.DisabledInDM = SettingManager.Common.ImgAzyobuziNetDisabledInDM; + imgazyobizinet.Enabled = this.settings.Common.EnableImgAzyobuziNet; + imgazyobizinet.DisabledInDM = this.settings.Common.ImgAzyobuziNetDisabledInDM; Thumbnail.Services.TonTwitterCom.GetApiConnection = () => this.twitterApi.Connection; // 画像投稿サービス - this.ImageSelector.Initialize(this.tw, this.tw.Configuration, SettingManager.Common.UseImageServiceName, SettingManager.Common.UseImageService); + this.ImageSelector.Initialize(this.tw, this.tw.Configuration, this.settings.Common.UseImageServiceName, this.settings.Common.UseImageService); // ハッシュタグ/@id関連 - this.AtIdSupl = new AtIdSupplement(SettingManager.AtIdList.AtIdList, "@"); - this.HashSupl = new AtIdSupplement(SettingManager.Common.HashTags, "#"); + this.AtIdSupl = new AtIdSupplement(this.settings.AtIdList.AtIdList, "@"); + this.HashSupl = new AtIdSupplement(this.settings.Common.HashTags, "#"); this.HashMgr = new HashtagManage(this.HashSupl, - SettingManager.Common.HashTags.ToArray(), - SettingManager.Common.HashSelected, - SettingManager.Common.HashIsPermanent, - SettingManager.Common.HashIsHead, - SettingManager.Common.HashIsNotAddToAtReply); + this.settings.Common.HashTags.ToArray(), + this.settings.Common.HashSelected, + this.settings.Common.HashIsPermanent, + this.settings.Common.HashIsHead, + this.settings.Common.HashIsNotAddToAtReply); if (!MyCommon.IsNullOrEmpty(this.HashMgr.UseHash) && this.HashMgr.IsPermanent) this.HashStripSplitButton.Text = this.HashMgr.UseHash; // アイコンリスト作成 @@ -929,27 +932,27 @@ private void TweenMain_Load(object sender, EventArgs e) this.tweetDetailsView.IconCache = this.iconCache; // フォント&文字色&背景色保持 - this.fntUnread = SettingManager.Local.FontUnread; - this.clUnread = SettingManager.Local.ColorUnread; - this.fntReaded = SettingManager.Local.FontRead; - this.clReaded = SettingManager.Local.ColorRead; - this.clFav = SettingManager.Local.ColorFav; - this.clOWL = SettingManager.Local.ColorOWL; - this.clRetweet = SettingManager.Local.ColorRetweet; - this.fntDetail = SettingManager.Local.FontDetail; - this.clDetail = SettingManager.Local.ColorDetail; - this.clDetailLink = SettingManager.Local.ColorDetailLink; - this.clDetailBackcolor = SettingManager.Local.ColorDetailBackcolor; - this.clSelf = SettingManager.Local.ColorSelf; - this.clAtSelf = SettingManager.Local.ColorAtSelf; - this.clTarget = SettingManager.Local.ColorTarget; - this.clAtTarget = SettingManager.Local.ColorAtTarget; - this.clAtFromTarget = SettingManager.Local.ColorAtFromTarget; - this.clAtTo = SettingManager.Local.ColorAtTo; - this.clListBackcolor = SettingManager.Local.ColorListBackcolor; - this.clInputBackcolor = SettingManager.Local.ColorInputBackcolor; - this.clInputFont = SettingManager.Local.ColorInputFont; - this.fntInputFont = SettingManager.Local.FontInputFont; + this.fntUnread = this.settings.Local.FontUnread; + this.clUnread = this.settings.Local.ColorUnread; + this.fntReaded = this.settings.Local.FontRead; + this.clReaded = this.settings.Local.ColorRead; + this.clFav = this.settings.Local.ColorFav; + this.clOWL = this.settings.Local.ColorOWL; + this.clRetweet = this.settings.Local.ColorRetweet; + this.fntDetail = this.settings.Local.FontDetail; + this.clDetail = this.settings.Local.ColorDetail; + this.clDetailLink = this.settings.Local.ColorDetailLink; + this.clDetailBackcolor = this.settings.Local.ColorDetailBackcolor; + this.clSelf = this.settings.Local.ColorSelf; + this.clAtSelf = this.settings.Local.ColorAtSelf; + this.clTarget = this.settings.Local.ColorTarget; + this.clAtTarget = this.settings.Local.ColorAtTarget; + this.clAtFromTarget = this.settings.Local.ColorAtFromTarget; + this.clAtTo = this.settings.Local.ColorAtTo; + this.clListBackcolor = this.settings.Local.ColorListBackcolor; + this.clInputBackcolor = this.settings.Local.ColorInputBackcolor; + this.clInputFont = this.settings.Local.ColorInputFont; + this.fntInputFont = this.settings.Local.FontInputFont; this.brsBackColorMine = new SolidBrush(this.clSelf); this.brsBackColorAt = new SolidBrush(this.clAtSelf); @@ -977,20 +980,20 @@ private void TweenMain_Load(object sender, EventArgs e) this.urlDialog.Owner = this; // 新着バルーン通知のチェック状態設定 - this.NewPostPopMenuItem.Checked = SettingManager.Common.NewAllPop; + this.NewPostPopMenuItem.Checked = this.settings.Common.NewAllPop; this.NotifyFileMenuItem.Checked = this.NewPostPopMenuItem.Checked; // 新着取得時のリストスクロールをするか。trueならスクロールしない - this.ListLockMenuItem.Checked = SettingManager.Common.ListLock; - this.LockListFileMenuItem.Checked = SettingManager.Common.ListLock; + this.ListLockMenuItem.Checked = this.settings.Common.ListLock; + this.LockListFileMenuItem.Checked = this.settings.Common.ListLock; // サウンド再生(タブ別設定より優先) - this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound; - this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound; + this.PlaySoundMenuItem.Checked = this.settings.Common.PlaySound; + this.PlaySoundFileMenuItem.Checked = this.settings.Common.PlaySound; // ウィンドウ設定 - this.ClientSize = ScaleBy(configScaleFactor, SettingManager.Local.FormSize); + this.ClientSize = ScaleBy(configScaleFactor, this.settings.Local.FormSize); this.mySize = this.ClientSize; // サイズ保持(最小化・最大化されたまま終了した場合の対応用) - this.myLoc = SettingManager.Local.FormLocation; + this.myLoc = this.settings.Local.FormLocation; // タイトルバー領域 if (this.WindowState != FormWindowState.Minimized) { @@ -1012,34 +1015,34 @@ private void TweenMain_Load(object sender, EventArgs e) } this.DesktopLocation = this.myLoc; } - this.TopMost = SettingManager.Common.AlwaysTop; - this.mySpDis = ScaleBy(configScaleFactor.Height, SettingManager.Local.SplitterDistance); - this.mySpDis2 = ScaleBy(configScaleFactor.Height, SettingManager.Local.StatusTextHeight); - if (SettingManager.Local.PreviewDistance == -1) + this.TopMost = this.settings.Common.AlwaysTop; + this.mySpDis = ScaleBy(configScaleFactor.Height, this.settings.Local.SplitterDistance); + this.mySpDis2 = ScaleBy(configScaleFactor.Height, this.settings.Local.StatusTextHeight); + if (this.settings.Local.PreviewDistance == -1) { this.mySpDis3 = this.mySize.Width - ScaleBy(this.CurrentScaleFactor.Width, 150); if (this.mySpDis3 < 1) this.mySpDis3 = ScaleBy(this.CurrentScaleFactor.Width, 50); - SettingManager.Local.PreviewDistance = this.mySpDis3; + this.settings.Local.PreviewDistance = this.mySpDis3; } else { - this.mySpDis3 = ScaleBy(configScaleFactor.Width, SettingManager.Local.PreviewDistance); + this.mySpDis3 = ScaleBy(configScaleFactor.Width, this.settings.Local.PreviewDistance); } - this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound; - this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound; + this.PlaySoundMenuItem.Checked = this.settings.Common.PlaySound; + this.PlaySoundFileMenuItem.Checked = this.settings.Common.PlaySound; // 入力欄 this.StatusText.Font = this.fntInputFont; this.StatusText.ForeColor = this.clInputFont; // SplitContainer2.Panel2MinSize を一行表示の入力欄の高さに合わせる (MS UI Gothic 12pt (96dpi) の場合は 19px) - this.StatusText.Multiline = false; // SettingManager.Local.StatusMultiline の設定は後で反映される + this.StatusText.Multiline = false; // this.settings.Local.StatusMultiline の設定は後で反映される this.SplitContainer2.Panel2MinSize = this.StatusText.Height; // 必要であれば、発言一覧と発言詳細部・入力欄の上下を入れ替える - this.SplitContainer1.IsPanelInverted = !SettingManager.Common.StatusAreaAtBottom; + this.SplitContainer1.IsPanelInverted = !this.settings.Common.StatusAreaAtBottom; // 全新着通知のチェック状態により、Reply&DMの新着通知有効無効切り替え(タブ別設定にするため削除予定) - if (SettingManager.Common.UnreadManage == false) + if (this.settings.Common.UnreadManage == false) { this.ReadedStripMenuItem.Enabled = false; this.UnreadStripMenuItem.Enabled = false; @@ -1065,8 +1068,8 @@ private void TweenMain_Load(object sender, EventArgs e) this.SplitContainer2.Panel2.AccessibleName = ""; //////////////////////////////////////////////////////////////////////////////// - var sortOrder = (SortOrder)SettingManager.Common.SortOrder; - var mode = SettingManager.Common.SortColumn switch + var sortOrder = (SortOrder)this.settings.Common.SortOrder; + var mode = this.settings.Common.SortColumn switch { // 0:アイコン,5:未読マーク,6:プロテクト・フィルターマーク 0 or 5 or 6 => ComparerMode.Id, // Idソートに読み替え @@ -1080,7 +1083,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.statuses.SetSortMode(mode, sortOrder); //////////////////////////////////////////////////////////////////////////////// - this.ApplyListViewIconSize(SettingManager.Common.IconSize); + this.ApplyListViewIconSize(this.settings.Common.IconSize); // <<<<<<<<タブ関連>>>>>>> foreach (var tab in this.statuses.Tabs) @@ -1097,7 +1100,7 @@ private void TweenMain_Load(object sender, EventArgs e) MyCommon.TwitterApiInfo.AccessLimitUpdated += this.TwitterApiStatus_AccessLimitUpdated; Microsoft.Win32.SystemEvents.TimeChanged += this.SystemEvents_TimeChanged; - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { this.ListTab.DrawMode = TabDrawMode.Normal; } @@ -1108,23 +1111,23 @@ private void TweenMain_Load(object sender, EventArgs e) this.ListTab.ImageList = null; } - if (SettingManager.Common.HotkeyEnabled) + if (this.settings.Common.HotkeyEnabled) { // グローバルホットキーの登録 var modKey = HookGlobalHotkey.ModKeys.None; - if ((SettingManager.Common.HotkeyModifier & Keys.Alt) == Keys.Alt) + if ((this.settings.Common.HotkeyModifier & Keys.Alt) == Keys.Alt) modKey |= HookGlobalHotkey.ModKeys.Alt; - if ((SettingManager.Common.HotkeyModifier & Keys.Control) == Keys.Control) + if ((this.settings.Common.HotkeyModifier & Keys.Control) == Keys.Control) modKey |= HookGlobalHotkey.ModKeys.Ctrl; - if ((SettingManager.Common.HotkeyModifier & Keys.Shift) == Keys.Shift) + if ((this.settings.Common.HotkeyModifier & Keys.Shift) == Keys.Shift) modKey |= HookGlobalHotkey.ModKeys.Shift; - if ((SettingManager.Common.HotkeyModifier & Keys.LWin) == Keys.LWin) + if ((this.settings.Common.HotkeyModifier & Keys.LWin) == Keys.LWin) modKey |= HookGlobalHotkey.ModKeys.Win; - this.hookGlobalHotkey.RegisterOriginalHotkey(SettingManager.Common.HotkeyKey, SettingManager.Common.HotkeyValue, modKey); + this.hookGlobalHotkey.RegisterOriginalHotkey(this.settings.Common.HotkeyKey, this.settings.Common.HotkeyValue, modKey); } - if (SettingManager.Common.IsUseNotifyGrowl) + if (this.settings.Common.IsUseNotifyGrowl) this.gh.RegisterGrowl(); this.StatusLabel.Text = Properties.Resources.Form1_LoadText1; // 画面右下の状態表示を変更 @@ -1132,7 +1135,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.SetMainWindowTitle(); this.SetNotifyIconText(); - if (!SettingManager.Common.MinimizeToTray || this.WindowState != FormWindowState.Minimized) + if (!this.settings.Common.MinimizeToTray || this.WindowState != FormWindowState.Minimized) { this.Visible = true; } @@ -1166,7 +1169,7 @@ private void TweenMain_Load(object sender, EventArgs e) this.TweenMain_Resize(this, EventArgs.Empty); if (saveRequired) this.SaveConfigsAll(false); - foreach (var ua in SettingManager.Common.UserAccounts) + foreach (var ua in this.settings.Common.UserAccounts) { if (ua.UserId == 0 && ua.Username.Equals(this.tw.Username, StringComparison.InvariantCultureIgnoreCase)) { @@ -1184,7 +1187,7 @@ private void TweenMain_Load(object sender, EventArgs e) private void InitDetailHtmlFormat() { - var htmlTemplate = SettingManager.Common.IsMonospace ? DetailHtmlFormatTemplateMono : DetailHtmlFormatTemplateNormal; + var htmlTemplate = this.settings.Common.IsMonospace ? DetailHtmlFormatTemplateMono : DetailHtmlFormatTemplateNormal; this.detailHtmlFormatPreparedTemplate = htmlTemplate .Replace("%FONT_FAMILY%", this.fntDetail.Name) @@ -1229,13 +1232,11 @@ private void ListTab_DrawItem(object sender, DrawItemEventArgs e) private void LoadConfig() { - SettingManager.Local = SettingManager.Local; - // v1.2.4 以前の設定には ScaleDimension の項目がないため、現在の DPI と同じとして扱う - if (SettingManager.Local.ScaleDimension.IsEmpty) - SettingManager.Local.ScaleDimension = this.CurrentAutoScaleDimensions; + if (this.settings.Local.ScaleDimension.IsEmpty) + this.settings.Local.ScaleDimension = this.CurrentAutoScaleDimensions; - var tabSettings = SettingManager.Tabs; + var tabSettings = this.settings.Tabs; foreach (var tabSetting in tabSettings.Tabs) { TabModel tab; @@ -1307,12 +1308,12 @@ private void RefreshTimelineScheduler() static TimeSpan IntervalSecondsOrDisabled(int seconds) => seconds == 0 ? Timeout.InfiniteTimeSpan : TimeSpan.FromSeconds(seconds); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = IntervalSecondsOrDisabled(SettingManager.Common.TimelinePeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Mention] = IntervalSecondsOrDisabled(SettingManager.Common.ReplyPeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Dm] = IntervalSecondsOrDisabled(SettingManager.Common.DMPeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.PublicSearch] = IntervalSecondsOrDisabled(SettingManager.Common.PubSearchPeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.User] = IntervalSecondsOrDisabled(SettingManager.Common.UserTimelinePeriod); - this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.List] = IntervalSecondsOrDisabled(SettingManager.Common.ListsPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Home] = IntervalSecondsOrDisabled(this.settings.Common.TimelinePeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Mention] = IntervalSecondsOrDisabled(this.settings.Common.ReplyPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Dm] = IntervalSecondsOrDisabled(this.settings.Common.DMPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.PublicSearch] = IntervalSecondsOrDisabled(this.settings.Common.PubSearchPeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.User] = IntervalSecondsOrDisabled(this.settings.Common.UserTimelinePeriod); + this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.List] = IntervalSecondsOrDisabled(this.settings.Common.ListsPeriod); this.timelineScheduler.UpdateInterval[TimelineSchedulerTaskType.Config] = TimeSpan.FromHours(6); this.timelineScheduler.UpdateAfterSystemResume = TimeSpan.FromSeconds(30); @@ -1400,7 +1401,7 @@ private void RefreshTimeline() if (addCount > 0) { - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { @@ -1639,7 +1640,7 @@ private bool BalloonRequired() return false; // 「画面最小化・アイコン時のみバルーンを表示する」が有効 - if (SettingManager.Common.LimitBalloon) + if (this.settings.Common.LimitBalloon) { if (this.WindowState != FormWindowState.Minimized && this.Visible && Form.ActiveForm != null) return false; @@ -1650,7 +1651,7 @@ private bool BalloonRequired() private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCount, bool newMentions) { - if (SettingManager.Common.ReadOwnPost) + if (this.settings.Common.ReadOwnPost) { if (notifyPosts != null && notifyPosts.Length > 0 && notifyPosts.All(x => x.UserId == this.tw.UserId)) return; @@ -1662,7 +1663,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo if (notifyPosts != null && notifyPosts.Length > 0) { // Growlは一個ずつばらして通知。ただし、3ポスト以上あるときはまとめる - if (SettingManager.Common.IsUseNotifyGrowl) + if (this.settings.Common.IsUseNotifyGrowl) { var sb = new StringBuilder(); var reply = false; @@ -1679,7 +1680,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo if (post.IsReply && !post.IsExcludeReply) reply = true; if (post.IsDm) dm = true; if (sb.Length > 0) sb.Append(System.Environment.NewLine); - switch (SettingManager.Common.NameBalloon) + switch (this.settings.Common.NameBalloon) { case MyCommon.NameBalloonEnum.UserID: sb.Append(post.ScreenName).Append(" : "); @@ -1696,7 +1697,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo var title = new StringBuilder(); GrowlHelper.NotifyType nt; - if (SettingManager.Common.DispUsername) + if (this.settings.Common.DispUsername) { title.Append(this.tw.Username); title.Append(" - "); @@ -1740,7 +1741,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo if (post.IsReply && !post.IsExcludeReply) reply = true; if (post.IsDm) dm = true; if (sb.Length > 0) sb.Append(System.Environment.NewLine); - switch (SettingManager.Common.NameBalloon) + switch (this.settings.Common.NameBalloon) { case MyCommon.NameBalloonEnum.UserID: sb.Append(post.ScreenName).Append(" : "); @@ -1754,7 +1755,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo var title = new StringBuilder(); ToolTipIcon ntIcon; - if (SettingManager.Common.DispUsername) + if (this.settings.Common.DispUsername) { title.Append(this.tw.Username); title.Append(" - "); @@ -1793,7 +1794,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo } // サウンド再生 - if (!this.initial && SettingManager.Common.PlaySound && !MyCommon.IsNullOrEmpty(soundFile)) + if (!this.initial && this.settings.Common.PlaySound && !MyCommon.IsNullOrEmpty(soundFile)) { try { @@ -1811,7 +1812,7 @@ private void NotifyNewPosts(PostClass[] notifyPosts, string soundFile, int addCo } // mentions新着時に画面ブリンク - if (!this.initial && SettingManager.Common.BlinkNewMentions && newMentions && Form.ActiveForm == null) + if (!this.initial && this.settings.Common.BlinkNewMentions && newMentions && Form.ActiveForm == null) { NativeMethods.FlashMyWindow(this.Handle, 3); } @@ -1850,7 +1851,7 @@ private void ChangeCacheStyleRead(bool read, int index) // Read:true=既読 false=未読 // 未読管理していなかったら既読として扱う if (!tabInfo.UnreadManage || - !SettingManager.Common.UnreadManage) read = true; + !this.settings.Common.UnreadManage) read = true; var listCache = this.listItemCache; if (listCache == null) @@ -1887,9 +1888,9 @@ private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post, D cl = this.clFav; else if (post.RetweetedId != null) cl = this.clRetweet; - else if (post.IsOwl && (post.IsDm || SettingManager.Common.OneWayLove)) + else if (post.IsOwl && (post.IsDm || this.settings.Common.OneWayLove)) cl = this.clOWL; - else if (read || !SettingManager.Common.UseUnreadStyle) + else if (read || !this.settings.Common.UseUnreadStyle) cl = this.clReaded; else cl = this.clUnread; @@ -1897,13 +1898,13 @@ private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post, D if (dList == null || item.Index == -1) { item.ForeColor = cl; - if (SettingManager.Common.UseUnreadStyle) + if (this.settings.Common.UseUnreadStyle) item.Font = fnt; } else { dList.Update(); - if (SettingManager.Common.UseUnreadStyle) + if (this.settings.Common.UseUnreadStyle) dList.ChangeItemFontAndColor(item, cl, fnt); else dList.ChangeItemForeColor(item, cl); @@ -2054,7 +2055,7 @@ private async void PostButton_Click(object sender, EventArgs e) this.history[this.history.Count - 1] = new StatusTextHistory(this.StatusText.Text, this.inReplyTo); - if (SettingManager.Common.Nicoms) + if (this.settings.Common.Nicoms) { this.StatusText.SelectionStart = this.StatusText.Text.Length; await this.UrlConvertAsync(MyCommon.UrlConverter.Nicoms); @@ -2116,7 +2117,7 @@ private async void PostButton_Click(object sender, EventArgs e) this.StatusText.Text = ""; this.history.Add(new StatusTextHistory("")); this.hisIdx = this.history.Count - 1; - if (!SettingManager.Common.FocusLockToStatusText) + if (!this.settings.Common.FocusLockToStatusText) this.CurrentListView.Focus(); this.urlUndoBuffer = null; this.UrlUndoToolStripMenuItem.Enabled = false; // Undoをできないように設定 @@ -2139,7 +2140,7 @@ private void EndToolStripMenuItem_Click(object sender, EventArgs e) private void TweenMain_FormClosing(object sender, FormClosingEventArgs e) { - if (!SettingManager.Common.CloseToExit && e.CloseReason == CloseReason.UserClosing && MyCommon.EndingFlag == false) + if (!this.settings.Common.CloseToExit && e.CloseReason == CloseReason.UserClosing && MyCommon.EndingFlag == false) { // _endingFlag=false:フォームの×ボタン e.Cancel = true; @@ -2293,7 +2294,7 @@ await this.twitterApi.FavoritesCreate(post.RetweetedId ?? post.StatusId) // エラーコード 139 のみの場合は成功と見なす } - if (SettingManager.Common.RestrictFavCheck) + if (this.settings.Common.RestrictFavCheck) { var status = await this.twitterApi.StatusesShow(post.RetweetedId ?? post.StatusId) .ConfigureAwait(false); @@ -2583,7 +2584,7 @@ await Task.Run(async () => this.StatusText.Focus(); // 連投モードのときだけEnterイベントが起きないので強制的に背景色を戻す - if (SettingManager.Common.FocusLockToStatusText) + if (this.settings.Common.FocusLockToStatusText) this.StatusText_Enter(this.StatusText, EventArgs.Empty); } return; @@ -2609,7 +2610,7 @@ await Task.Run(async () => this.SetMainWindowTitle(); // TLに反映 - if (SettingManager.Common.PostAndGet) + if (this.settings.Common.PostAndGet) { await this.RefreshTabAsync(); } @@ -2655,10 +2656,10 @@ private async Task RetweetAsyncInternal(IProgress p, CancellationToken c throw new WebApiException("Auth error. Check your account"); bool read; - if (!SettingManager.Common.UnreadManage) + if (!this.settings.Common.UnreadManage) read = true; else - read = this.initial && SettingManager.Common.Read; + read = this.initial && this.settings.Common.Read; p.Report("Posting..."); @@ -2691,7 +2692,7 @@ await Task.Run(async () => // 投稿時取得の有無に関わらず追加しておく posts.ForEach(post => this.statuses.AddPost(post)); - if (SettingManager.Common.PostAndGet) + if (this.settings.Common.PostAndGet) { await this.RefreshTabAsync(); } @@ -2839,7 +2840,7 @@ private async void MyList_MouseDoubleClick(object sender, MouseEventArgs e) private async Task ListItemDoubleClickAction() { - switch (SettingManager.Common.ListDoubleClickAction) + switch (this.settings.Common.ListDoubleClickAction) { case MyCommon.ListItemDoubleClickActionType.Reply: this.MakeReplyText(); @@ -3054,7 +3055,7 @@ private void SetSortLastColumn() /// private void SetSortColumn(ComparerMode sortColumn) { - if (SettingManager.Common.SortOrderLock) + if (this.settings.Common.SortOrderLock) return; this.statuses.ToggleSortOrder(sortColumn); @@ -3308,14 +3309,14 @@ await this.twitterApi.StatusesDestroy(post.StatusId) } } - if (SettingManager.Common.TabIconDisp && tab.UnreadCount == 0) + if (this.settings.Common.TabIconDisp && tab.UnreadCount == 0) { if (tabPage.ImageIndex == 0) tabPage.ImageIndex = -1; // タブアイコン } } - if (!SettingManager.Common.TabIconDisp) + if (!this.settings.Common.TabIconDisp) this.ListTab.Refresh(); } } @@ -3336,7 +3337,7 @@ private void ReadedStripMenuItem_Click(object sender, EventArgs e) } this.ColorizeList(); } - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { @@ -3348,7 +3349,7 @@ private void ReadedStripMenuItem_Click(object sender, EventArgs e) } } } - if (!SettingManager.Common.TabIconDisp) this.ListTab.Refresh(); + if (!this.settings.Common.TabIconDisp) this.ListTab.Refresh(); } private void UnreadStripMenuItem_Click(object sender, EventArgs e) @@ -3364,7 +3365,7 @@ private void UnreadStripMenuItem_Click(object sender, EventArgs e) } this.ColorizeList(); } - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { @@ -3376,7 +3377,7 @@ private void UnreadStripMenuItem_Click(object sender, EventArgs e) } } } - if (!SettingManager.Common.TabIconDisp) this.ListTab.Refresh(); + if (!this.settings.Common.TabIconDisp) this.ListTab.Refresh(); } private async void RefreshStripMenuItem_Click(object sender, EventArgs e) @@ -3401,7 +3402,7 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) settingDialog.Tw = this.tw; settingDialog.TwitterApi = this.twitterApi; - settingDialog.LoadConfig(SettingManager.Common, SettingManager.Local); + settingDialog.LoadConfig(this.settings.Common, this.settings.Local); try { @@ -3416,7 +3417,7 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) { lock (this.syncObject) { - settingDialog.SaveConfig(SettingManager.Common, SettingManager.Local); + settingDialog.SaveConfig(this.settings.Common, this.settings.Local); } } @@ -3428,35 +3429,35 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) // 設定画面表示前のユーザー情報 var oldUser = new { this.tw.AccessToken, this.tw.AccessTokenSecret, this.tw.Username, this.tw.UserId }; - var oldIconSz = SettingManager.Common.IconSize; + var oldIconSz = this.settings.Common.IconSize; if (this.ShowSettingDialog() == DialogResult.OK) { lock (this.syncObject) { - this.tw.RestrictFavCheck = SettingManager.Common.RestrictFavCheck; - this.tw.ReadOwnPost = SettingManager.Common.ReadOwnPost; - ShortUrl.Instance.DisableExpanding = !SettingManager.Common.TinyUrlResolve; - ShortUrl.Instance.BitlyAccessToken = SettingManager.Common.BitlyAccessToken; - ShortUrl.Instance.BitlyId = SettingManager.Common.BilyUser; - ShortUrl.Instance.BitlyKey = SettingManager.Common.BitlyPwd; - TwitterApiConnection.RestApiHost = SettingManager.Common.TwitterApiHost; + this.tw.RestrictFavCheck = this.settings.Common.RestrictFavCheck; + this.tw.ReadOwnPost = this.settings.Common.ReadOwnPost; + ShortUrl.Instance.DisableExpanding = !this.settings.Common.TinyUrlResolve; + ShortUrl.Instance.BitlyAccessToken = this.settings.Common.BitlyAccessToken; + ShortUrl.Instance.BitlyId = this.settings.Common.BilyUser; + ShortUrl.Instance.BitlyKey = this.settings.Common.BitlyPwd; + TwitterApiConnection.RestApiHost = this.settings.Common.TwitterApiHost; - Networking.DefaultTimeout = TimeSpan.FromSeconds(SettingManager.Common.DefaultTimeOut); - Networking.UploadImageTimeout = TimeSpan.FromSeconds(SettingManager.Common.UploadImageTimeout); + Networking.DefaultTimeout = TimeSpan.FromSeconds(this.settings.Common.DefaultTimeOut); + Networking.UploadImageTimeout = TimeSpan.FromSeconds(this.settings.Common.UploadImageTimeout); Networking.SetWebProxy( - SettingManager.Local.ProxyType, - SettingManager.Local.ProxyAddress, - SettingManager.Local.ProxyPort, - SettingManager.Local.ProxyUser, - SettingManager.Local.ProxyPassword); - Networking.ForceIPv4 = SettingManager.Common.ForceIPv4; + this.settings.Local.ProxyType, + this.settings.Local.ProxyAddress, + this.settings.Local.ProxyPort, + this.settings.Local.ProxyUser, + this.settings.Local.ProxyPassword); + Networking.ForceIPv4 = this.settings.Common.ForceIPv4; this.ImageSelector.Reset(this.tw, this.tw.Configuration); try { - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { this.ListTab.DrawItem -= this.ListTab_DrawItem; this.ListTab.DrawMode = TabDrawMode.Normal; @@ -3479,11 +3480,11 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) try { - if (!SettingManager.Common.UnreadManage) + if (!this.settings.Common.UnreadManage) { this.ReadedStripMenuItem.Enabled = false; this.UnreadStripMenuItem.Enabled = false; - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { foreach (TabPage myTab in this.ListTab.TabPages) { @@ -3507,37 +3508,37 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) // タブの表示位置の決定 this.SetTabAlignment(); - this.SplitContainer1.IsPanelInverted = !SettingManager.Common.StatusAreaAtBottom; + this.SplitContainer1.IsPanelInverted = !this.settings.Common.StatusAreaAtBottom; var imgazyobizinet = ThumbnailGenerator.ImgAzyobuziNetInstance; - imgazyobizinet.Enabled = SettingManager.Common.EnableImgAzyobuziNet; - imgazyobizinet.DisabledInDM = SettingManager.Common.ImgAzyobuziNetDisabledInDM; - - this.NewPostPopMenuItem.Checked = SettingManager.Common.NewAllPop; - this.NotifyFileMenuItem.Checked = SettingManager.Common.NewAllPop; - this.PlaySoundMenuItem.Checked = SettingManager.Common.PlaySound; - this.PlaySoundFileMenuItem.Checked = SettingManager.Common.PlaySound; - this.fntUnread = SettingManager.Local.FontUnread; - this.clUnread = SettingManager.Local.ColorUnread; - this.fntReaded = SettingManager.Local.FontRead; - this.clReaded = SettingManager.Local.ColorRead; - this.clFav = SettingManager.Local.ColorFav; - this.clOWL = SettingManager.Local.ColorOWL; - this.clRetweet = SettingManager.Local.ColorRetweet; - this.fntDetail = SettingManager.Local.FontDetail; - this.clDetail = SettingManager.Local.ColorDetail; - this.clDetailLink = SettingManager.Local.ColorDetailLink; - this.clDetailBackcolor = SettingManager.Local.ColorDetailBackcolor; - this.clSelf = SettingManager.Local.ColorSelf; - this.clAtSelf = SettingManager.Local.ColorAtSelf; - this.clTarget = SettingManager.Local.ColorTarget; - this.clAtTarget = SettingManager.Local.ColorAtTarget; - this.clAtFromTarget = SettingManager.Local.ColorAtFromTarget; - this.clAtTo = SettingManager.Local.ColorAtTo; - this.clListBackcolor = SettingManager.Local.ColorListBackcolor; - this.clInputBackcolor = SettingManager.Local.ColorInputBackcolor; - this.clInputFont = SettingManager.Local.ColorInputFont; - this.fntInputFont = SettingManager.Local.FontInputFont; + imgazyobizinet.Enabled = this.settings.Common.EnableImgAzyobuziNet; + imgazyobizinet.DisabledInDM = this.settings.Common.ImgAzyobuziNetDisabledInDM; + + this.NewPostPopMenuItem.Checked = this.settings.Common.NewAllPop; + this.NotifyFileMenuItem.Checked = this.settings.Common.NewAllPop; + this.PlaySoundMenuItem.Checked = this.settings.Common.PlaySound; + this.PlaySoundFileMenuItem.Checked = this.settings.Common.PlaySound; + this.fntUnread = this.settings.Local.FontUnread; + this.clUnread = this.settings.Local.ColorUnread; + this.fntReaded = this.settings.Local.FontRead; + this.clReaded = this.settings.Local.ColorRead; + this.clFav = this.settings.Local.ColorFav; + this.clOWL = this.settings.Local.ColorOWL; + this.clRetweet = this.settings.Local.ColorRetweet; + this.fntDetail = this.settings.Local.FontDetail; + this.clDetail = this.settings.Local.ColorDetail; + this.clDetailLink = this.settings.Local.ColorDetailLink; + this.clDetailBackcolor = this.settings.Local.ColorDetailBackcolor; + this.clSelf = this.settings.Local.ColorSelf; + this.clAtSelf = this.settings.Local.ColorAtSelf; + this.clTarget = this.settings.Local.ColorTarget; + this.clAtTarget = this.settings.Local.ColorAtTarget; + this.clAtFromTarget = this.settings.Local.ColorAtFromTarget; + this.clAtTo = this.settings.Local.ColorAtTo; + this.clListBackcolor = this.settings.Local.ColorListBackcolor; + this.clInputBackcolor = this.settings.Local.ColorInputBackcolor; + this.clInputFont = this.settings.Local.ColorInputFont; + this.fntInputFont = this.settings.Local.FontInputFont; this.brsBackColorMine.Dispose(); this.brsBackColorAt.Dispose(); this.brsBackColorYou.Dispose(); @@ -3577,7 +3578,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) try { - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { @@ -3600,8 +3601,8 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) { var oldIconCol = this.iconCol; - if (SettingManager.Common.IconSize != oldIconSz) - this.ApplyListViewIconSize(SettingManager.Common.IconSize); + if (this.settings.Common.IconSize != oldIconSz) + this.ApplyListViewIconSize(this.settings.Common.IconSize); foreach (TabPage tp in this.ListTab.TabPages) { @@ -3609,7 +3610,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) using (ControlTransaction.Update(lst)) { - lst.GridLines = SettingManager.Common.ShowGrid; + lst.GridLines = this.settings.Common.ShowGrid; lst.Font = this.fntReaded; lst.BackColor = this.clListBackcolor; @@ -3633,23 +3634,23 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) this.ListTab.Refresh(); this.hookGlobalHotkey.UnregisterAllOriginalHotkey(); - if (SettingManager.Common.HotkeyEnabled) + if (this.settings.Common.HotkeyEnabled) { // グローバルホットキーの登録。設定で変更可能にするかも var modKey = HookGlobalHotkey.ModKeys.None; - if ((SettingManager.Common.HotkeyModifier & Keys.Alt) == Keys.Alt) + if ((this.settings.Common.HotkeyModifier & Keys.Alt) == Keys.Alt) modKey |= HookGlobalHotkey.ModKeys.Alt; - if ((SettingManager.Common.HotkeyModifier & Keys.Control) == Keys.Control) + if ((this.settings.Common.HotkeyModifier & Keys.Control) == Keys.Control) modKey |= HookGlobalHotkey.ModKeys.Ctrl; - if ((SettingManager.Common.HotkeyModifier & Keys.Shift) == Keys.Shift) + if ((this.settings.Common.HotkeyModifier & Keys.Shift) == Keys.Shift) modKey |= HookGlobalHotkey.ModKeys.Shift; - if ((SettingManager.Common.HotkeyModifier & Keys.LWin) == Keys.LWin) + if ((this.settings.Common.HotkeyModifier & Keys.LWin) == Keys.LWin) modKey |= HookGlobalHotkey.ModKeys.Win; - this.hookGlobalHotkey.RegisterOriginalHotkey(SettingManager.Common.HotkeyKey, SettingManager.Common.HotkeyValue, modKey); + this.hookGlobalHotkey.RegisterOriginalHotkey(this.settings.Common.HotkeyKey, this.settings.Common.HotkeyValue, modKey); } - if (SettingManager.Common.IsUseNotifyGrowl) this.gh.RegisterGrowl(); + if (this.settings.Common.IsUseNotifyGrowl) this.gh.RegisterGrowl(); try { this.StatusText_TextChanged(this.StatusText, EventArgs.Empty); @@ -3667,7 +3668,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid; - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; this.SaveConfigsAll(false); if (this.tw.UserId != oldUser.UserId) @@ -3679,7 +3680,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) /// private void SetTabAlignment() { - var newAlignment = SettingManager.Common.ViewTabBottom ? TabAlignment.Bottom : TabAlignment.Top; + var newAlignment = this.settings.Common.ViewTabBottom ? TabAlignment.Bottom : TabAlignment.Top; if (this.ListTab.Alignment == newAlignment) return; // 各タブのリスト上の選択位置などを退避 @@ -4019,7 +4020,7 @@ public bool AddNewTab(TabModel tab, bool startup) listCustom.Font = this.fntReaded; listCustom.BackColor = this.clListBackcolor; - listCustom.GridLines = SettingManager.Common.ShowGrid; + listCustom.GridLines = this.settings.Common.ShowGrid; listCustom.AllowDrop = true; listCustom.SmallImageList = this.listViewImageList; @@ -4179,7 +4180,7 @@ private void ListTab_MouseMove(object sender, MouseEventArgs e) { // タブのD&D - if (!SettingManager.Common.TabMouseLock && e.Button == MouseButtons.Left && this.tabDrag) + if (!this.settings.Common.TabMouseLock && e.Button == MouseButtons.Left && this.tabDrag) { var tn = ""; var dragEnableRectangle = new Rectangle(this.tabMouseDownPoint.X - (SystemInformation.DragSize.Width / 2), this.tabMouseDownPoint.Y - (SystemInformation.DragSize.Height / 2), SystemInformation.DragSize.Width, SystemInformation.DragSize.Height); @@ -4270,7 +4271,7 @@ private void StatusText_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == '@') { - if (!SettingManager.Common.UseAtIdSupplement) return; + if (!this.settings.Common.UseAtIdSupplement) return; // @マーク var cnt = this.AtIdSupl.ItemCount; this.ShowSuplDialog(this.StatusText, this.AtIdSupl); @@ -4280,7 +4281,7 @@ private void StatusText_KeyPress(object sender, KeyPressEventArgs e) } else if (e.KeyChar == '#') { - if (!SettingManager.Common.UseHashSupplement) return; + if (!this.settings.Common.UseHashSupplement) return; this.ShowSuplDialog(this.StatusText, this.HashSupl); e.Handled = true; } @@ -4303,7 +4304,7 @@ public void ShowSuplDialog(TextBox owner, AtIdSupplement dialog, int offset, str { dialog.ShowDialog(); } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; var selStart = owner.SelectionStart; var fHalf = ""; var eHalf = ""; @@ -4504,7 +4505,7 @@ private string FormatStatusText(string statusText) statusText = Regex.Replace(statusText, @"https?:\/\/[-_.!~*'()a-zA-Z0-9;\/?:\@&=+\$,%#^]+", "$& "); } - if (SettingManager.Common.WideSpaceConvert) + if (this.settings.Common.WideSpaceConvert) { // 文中の全角スペースを半角スペース1個にする statusText = statusText.Replace(" ", " "); @@ -4515,13 +4516,13 @@ private string FormatStatusText(string statusText) return statusText; bool disableFooter; - if (SettingManager.Common.PostShiftEnter) + if (this.settings.Common.PostShiftEnter) { disableFooter = MyCommon.IsKeyDown(Keys.Control); } else { - if (this.StatusText.Multiline && !SettingManager.Common.PostCtrlEnter) + if (this.StatusText.Multiline && !this.settings.Common.PostCtrlEnter) disableFooter = MyCommon.IsKeyDown(Keys.Control); else disableFooter = MyCommon.IsKeyDown(Keys.Shift); @@ -4555,15 +4556,15 @@ private string FormatStatusText(string statusText) if (!disableFooter) { - if (SettingManager.Local.UseRecommendStatus) + if (this.settings.Local.UseRecommendStatus) { // 推奨ステータスを使用する footer += this.recommendedStatusFooter; } - else if (!MyCommon.IsNullOrEmpty(SettingManager.Local.StatusText)) + else if (!MyCommon.IsNullOrEmpty(this.settings.Local.StatusText)) { // テキストボックスに入力されている文字列を使用する - footer += " " + SettingManager.Local.StatusText.Trim(); + footer += " " + this.settings.Local.StatusText.Trim(); } } @@ -4704,7 +4705,7 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) "", post.Nickname, post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), - post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), + post.CreatedAt.ToLocalTimeString(this.settings.Common.DateTimeFormat), post.ScreenName, "", mk.ToString(), @@ -4719,7 +4720,7 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) "", post.Nickname, post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), - post.CreatedAt.ToLocalTimeString(SettingManager.Common.DateTimeFormat), + post.CreatedAt.ToLocalTimeString(this.settings.Common.DateTimeFormat), post.ScreenName + Environment.NewLine + "(RT:" + post.RetweetedBy + ")", "", mk.ToString(), @@ -4732,7 +4733,7 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) var read = post.IsRead; // 未読管理していなかったら既読として扱う - if (!tab.UnreadManage || !SettingManager.Common.UnreadManage) + if (!tab.UnreadManage || !this.settings.Common.UnreadManage) read = true; this.ChangeItemStyleRead(read, itm, post, null); @@ -4762,7 +4763,7 @@ private void ApplyPostFilters() listview.VirtualListSize = tab.AllCount; } - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { if (tab.UnreadCount > 0) tabPage.ImageIndex = 0; @@ -4771,7 +4772,7 @@ private void ApplyPostFilters() } } - if (!SettingManager.Common.TabIconDisp) + if (!this.settings.Common.TabIconDisp) this.ListTab.Refresh(); this.SetMainWindowTitle(); @@ -5120,10 +5121,10 @@ private void ShowSearchDialog() { if (this.SearchDialog.ShowDialog(this) != DialogResult.OK) { - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; return; } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; var searchOptions = this.SearchDialog.ResultOptions!; if (searchOptions.Type == SearchWordDialog.SearchType.Timeline) @@ -5219,7 +5220,7 @@ private void AboutMenuItem_Click(object sender, EventArgs e) { about.ShowDialog(this); } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; } private void JumpUnreadMenuItem_Click(object sender, EventArgs e) @@ -5401,7 +5402,7 @@ private async Task CheckNewVersion(bool startup = false) return; } - if (startup && versionInfo.Version <= SettingManager.Common.SkipUpdateVersion) + if (startup && versionInfo.Version <= this.settings.Common.SkipUpdateVersion) return; using var dialog = new UpdateDialog(); @@ -5416,7 +5417,7 @@ private async Task CheckNewVersion(bool startup = false) } else if (dialog.SkipButtonPressed) { - SettingManager.Common.SkipUpdateVersion = versionInfo.Version; + this.settings.Common.SkipUpdateVersion = versionInfo.Version; this.MarkSettingCommonModified(); } } @@ -5438,17 +5439,17 @@ private async Task CheckNewVersion(bool startup = false) private void UpdateSelectedPost() { // 件数関連の場合、タイトル即時書き換え - if (SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.None && - SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Post && - SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver && - SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus) + if (this.settings.Common.DispLatestPost != MyCommon.DispTitleEnum.None && + this.settings.Common.DispLatestPost != MyCommon.DispTitleEnum.Post && + this.settings.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver && + this.settings.Common.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus) { this.SetMainWindowTitle(); } if (!this.StatusLabelUrl.Text.StartsWith("http", StringComparison.OrdinalIgnoreCase)) this.SetStatusLabelUrl(); - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { @@ -5500,7 +5501,7 @@ private void DispSelectedPost(bool forceupdate) this.SplitContainer3.Panel2Collapsed = true; - if (SettingManager.Common.PreviewEnable) + if (this.settings.Common.PreviewEnable) { var oldTokenSource = Interlocked.Exchange(ref this.thumbnailTokenSource, new CancellationTokenSource()); oldTokenSource?.Cancel(); @@ -5875,8 +5876,8 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.PostBrowser) .Do(() => { - var multiline = !SettingManager.Local.StatusMultiline; - SettingManager.Local.StatusMultiline = multiline; + var multiline = !this.settings.Local.StatusMultiline; + this.settings.Local.StatusMultiline = multiline; this.MultiLineMenuItem.Checked = multiline; this.MultiLineMenuItem_Click(this.MultiLineMenuItem, EventArgs.Empty); }), @@ -6979,11 +6980,11 @@ private void SaveConfigsAll(bool ifModified) private void SaveConfigsAtId() { - if (this.ignoreConfigSave || !SettingManager.Common.UseAtIdSupplement && this.AtIdSupl == null) return; + if (this.ignoreConfigSave || !this.settings.Common.UseAtIdSupplement && this.AtIdSupl == null) return; this.ModifySettingAtId = false; - SettingManager.AtIdList.AtIdList = this.AtIdSupl.GetItemList(); - SettingManager.SaveAtIdList(); + this.settings.AtIdList.AtIdList = this.AtIdSupl.GetItemList(); + this.settings.SaveAtIdList(); } private void SaveConfigsCommon() @@ -6993,12 +6994,12 @@ private void SaveConfigsCommon() this.ModifySettingCommon = false; lock (this.syncObject) { - SettingManager.Common.UserName = this.tw.Username; - SettingManager.Common.UserId = this.tw.UserId; - SettingManager.Common.Token = this.tw.AccessToken; - SettingManager.Common.TokenSecret = this.tw.AccessTokenSecret; - SettingManager.Common.SortOrder = (int)this.statuses.SortOrder; - SettingManager.Common.SortColumn = this.statuses.SortMode switch + this.settings.Common.UserName = this.tw.Username; + this.settings.Common.UserId = this.tw.UserId; + this.settings.Common.Token = this.tw.AccessToken; + this.settings.Common.TokenSecret = this.tw.AccessTokenSecret; + this.settings.Common.SortOrder = (int)this.statuses.SortOrder; + this.settings.Common.SortColumn = this.statuses.SortMode switch { ComparerMode.Nickname => 1, // ニックネーム ComparerMode.Data => 2, // 本文 @@ -7007,22 +7008,22 @@ private void SaveConfigsCommon() ComparerMode.Source => 7, // Source _ => throw new InvalidOperationException($"Invalid sort mode: {this.statuses.SortMode}"), }; - SettingManager.Common.HashTags = this.HashMgr.HashHistories; + this.settings.Common.HashTags = this.HashMgr.HashHistories; if (this.HashMgr.IsPermanent) { - SettingManager.Common.HashSelected = this.HashMgr.UseHash; + this.settings.Common.HashSelected = this.HashMgr.UseHash; } else { - SettingManager.Common.HashSelected = ""; + this.settings.Common.HashSelected = ""; } - SettingManager.Common.HashIsHead = this.HashMgr.IsHead; - SettingManager.Common.HashIsPermanent = this.HashMgr.IsPermanent; - SettingManager.Common.HashIsNotAddToAtReply = this.HashMgr.IsNotAddToAtReply; - SettingManager.Common.UseImageService = this.ImageSelector.ServiceIndex; - SettingManager.Common.UseImageServiceName = this.ImageSelector.ServiceName; + this.settings.Common.HashIsHead = this.HashMgr.IsHead; + this.settings.Common.HashIsPermanent = this.HashMgr.IsPermanent; + this.settings.Common.HashIsNotAddToAtReply = this.HashMgr.IsNotAddToAtReply; + this.settings.Common.UseImageService = this.ImageSelector.ServiceIndex; + this.settings.Common.UseImageServiceName = this.ImageSelector.ServiceName; - SettingManager.SaveCommon(); + this.settings.SaveCommon(); } } @@ -7032,38 +7033,38 @@ private void SaveConfigsLocal() lock (this.syncObject) { this.ModifySettingLocal = false; - SettingManager.Local.ScaleDimension = this.CurrentAutoScaleDimensions; - SettingManager.Local.FormSize = this.mySize; - SettingManager.Local.FormLocation = this.myLoc; - SettingManager.Local.SplitterDistance = this.mySpDis; - SettingManager.Local.PreviewDistance = this.mySpDis3; - SettingManager.Local.StatusMultiline = this.StatusText.Multiline; - SettingManager.Local.StatusTextHeight = this.mySpDis2; - - SettingManager.Local.FontUnread = this.fntUnread; - SettingManager.Local.ColorUnread = this.clUnread; - SettingManager.Local.FontRead = this.fntReaded; - SettingManager.Local.ColorRead = this.clReaded; - SettingManager.Local.FontDetail = this.fntDetail; - SettingManager.Local.ColorDetail = this.clDetail; - SettingManager.Local.ColorDetailBackcolor = this.clDetailBackcolor; - SettingManager.Local.ColorDetailLink = this.clDetailLink; - SettingManager.Local.ColorFav = this.clFav; - SettingManager.Local.ColorOWL = this.clOWL; - SettingManager.Local.ColorRetweet = this.clRetweet; - SettingManager.Local.ColorSelf = this.clSelf; - SettingManager.Local.ColorAtSelf = this.clAtSelf; - SettingManager.Local.ColorTarget = this.clTarget; - SettingManager.Local.ColorAtTarget = this.clAtTarget; - SettingManager.Local.ColorAtFromTarget = this.clAtFromTarget; - SettingManager.Local.ColorAtTo = this.clAtTo; - SettingManager.Local.ColorListBackcolor = this.clListBackcolor; - SettingManager.Local.ColorInputBackcolor = this.clInputBackcolor; - SettingManager.Local.ColorInputFont = this.clInputFont; - SettingManager.Local.FontInputFont = this.fntInputFont; + this.settings.Local.ScaleDimension = this.CurrentAutoScaleDimensions; + this.settings.Local.FormSize = this.mySize; + this.settings.Local.FormLocation = this.myLoc; + this.settings.Local.SplitterDistance = this.mySpDis; + this.settings.Local.PreviewDistance = this.mySpDis3; + this.settings.Local.StatusMultiline = this.StatusText.Multiline; + this.settings.Local.StatusTextHeight = this.mySpDis2; + + this.settings.Local.FontUnread = this.fntUnread; + this.settings.Local.ColorUnread = this.clUnread; + this.settings.Local.FontRead = this.fntReaded; + this.settings.Local.ColorRead = this.clReaded; + this.settings.Local.FontDetail = this.fntDetail; + this.settings.Local.ColorDetail = this.clDetail; + this.settings.Local.ColorDetailBackcolor = this.clDetailBackcolor; + this.settings.Local.ColorDetailLink = this.clDetailLink; + this.settings.Local.ColorFav = this.clFav; + this.settings.Local.ColorOWL = this.clOWL; + this.settings.Local.ColorRetweet = this.clRetweet; + this.settings.Local.ColorSelf = this.clSelf; + this.settings.Local.ColorAtSelf = this.clAtSelf; + this.settings.Local.ColorTarget = this.clTarget; + this.settings.Local.ColorAtTarget = this.clAtTarget; + this.settings.Local.ColorAtFromTarget = this.clAtFromTarget; + this.settings.Local.ColorAtTo = this.clAtTo; + this.settings.Local.ColorListBackcolor = this.clListBackcolor; + this.settings.Local.ColorInputBackcolor = this.clInputBackcolor; + this.settings.Local.ColorInputFont = this.clInputFont; + this.settings.Local.FontInputFont = this.fntInputFont; if (this.ignoreConfigSave) return; - SettingManager.SaveLocal(); + this.settings.SaveLocal(); } } @@ -7108,8 +7109,8 @@ private void SaveConfigsTabs() tabSettingList.Add(tabSetting); } - SettingManager.Tabs.Tabs = tabSettingList; - SettingManager.SaveTabs(); + this.settings.Tabs.Tabs = tabSettingList; + this.settings.SaveTabs(); } private async void OpenURLFileMenuItem_Click(object sender, EventArgs e) @@ -7200,7 +7201,7 @@ private void SaveLogMenuItem_Click(object sender, EventArgs e) } } } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; } public bool TabRename(string origTabName, [NotNullWhen(true)] out string? newTabName) @@ -7214,7 +7215,7 @@ public bool TabRename(string origTabName, [NotNullWhen(true)] out string? newTab if (inputName.DialogResult == DialogResult.Cancel) return false; newTabName = inputName.TabName; } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; if (!MyCommon.IsNullOrEmpty(newTabName)) { // 新タブ名存在チェック @@ -7266,7 +7267,7 @@ private void ListTab_DoubleClick(object sender, MouseEventArgs e) private void ListTab_MouseDown(object sender, MouseEventArgs e) { - if (SettingManager.Common.TabMouseLock) return; + if (this.settings.Common.TabMouseLock) return; if (e.Button == MouseButtons.Left) { foreach (var i in Enumerable.Range(0, this.statuses.Tabs.Count)) @@ -7463,7 +7464,7 @@ void DisableTasktrayAnimation() return; } - var replyIconType = SettingManager.Common.ReplyIconState; + var replyIconType = this.settings.Common.ReplyIconState; var reply = false; if (replyIconType != MyCommon.REPLY_ICONSTATE.None) { @@ -7620,7 +7621,7 @@ public void ChangeTabUnreadManage(string tabName, bool isManage) var tab = this.statuses.Tabs[tabName]; tab.UnreadManage = isManage; - if (SettingManager.Common.TabIconDisp) + if (this.settings.Common.TabIconDisp) { var tabPage = this.ListTab.TabPages[idx]; if (tab.UnreadCount > 0) @@ -7637,7 +7638,7 @@ public void ChangeTabUnreadManage(string tabName, bool isManage) this.SetMainWindowTitle(); this.SetStatusLabelUrl(); - if (!SettingManager.Common.TabIconDisp) this.ListTab.Refresh(); + if (!this.settings.Common.TabIconDisp) this.ListTab.Refresh(); } private void NotifyDispMenuItem_Click(object sender, EventArgs e) @@ -7680,7 +7681,7 @@ private void FilterEditMenuItem_Click(object sender, EventArgs e) fltDialog.SetCurrent(this.rclickTabName); fltDialog.ShowDialog(this); } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; this.ApplyPostFilters(); this.SaveConfigsTabs(); @@ -7699,7 +7700,7 @@ private async void AddTabMenuItem_Click(object sender, EventArgs e) tabName = inputName.TabName; tabUsage = inputName.Usage; } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; if (!MyCommon.IsNullOrEmpty(tabName)) { // List対応 @@ -7781,7 +7782,7 @@ private void TabMenuItem_Click(object sender, EventArgs e) fltDialog.ShowDialog(this); } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; } this.ApplyPostFilters(); @@ -7798,7 +7799,7 @@ protected override bool ProcessDialogKey(Keys keyData) var newLine = false; var post = false; - if (SettingManager.Common.PostCtrlEnter) // Ctrl+Enter投稿時 + if (this.settings.Common.PostCtrlEnter) // Ctrl+Enter投稿時 { if (this.StatusText.Multiline) { @@ -7811,7 +7812,7 @@ protected override bool ProcessDialogKey(Keys keyData) if ((keyData & Keys.Control) == Keys.Control) post = true; } } - else if (SettingManager.Common.PostShiftEnter) // SHift+Enter投稿時 + else if (this.settings.Common.PostShiftEnter) // SHift+Enter投稿時 { if (this.StatusText.Multiline) { @@ -8020,7 +8021,7 @@ private bool SelectTab([NotNullWhen(true)] out FilterTabModel? tab) if (inputName.DialogResult == DialogResult.Cancel) return false; tabName = inputName.TabName; } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; if (!MyCommon.IsNullOrEmpty(tabName)) { var newTab = new FilterTabModel(tabName); @@ -8166,7 +8167,7 @@ private async void OpenURLMenuItem_Click(object sender, EventArgs e) if (this.urlDialog.ShowDialog(this) != DialogResult.OK) return; - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; selectedUrl = this.urlDialog.SelectedUrl; @@ -8209,7 +8210,7 @@ private void ClearTab(string tabName, bool showWarning) var listView = (DetailsListView)tabPage.Tag; listView.VirtualListSize = 0; - if (!SettingManager.Common.TabIconDisp) this.ListTab.Refresh(); + if (!this.settings.Common.TabIconDisp) this.ListTab.Refresh(); this.SetMainWindowTitle(); this.SetStatusLabelUrl(); @@ -8223,10 +8224,10 @@ private void SetMainWindowTitle() var ttl = new StringBuilder(256); var ur = 0; var al = 0; - if (SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.None && - SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Post && - SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver && - SettingManager.Common.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus) + if (this.settings.Common.DispLatestPost != MyCommon.DispTitleEnum.None && + this.settings.Common.DispLatestPost != MyCommon.DispTitleEnum.Post && + this.settings.Common.DispLatestPost != MyCommon.DispTitleEnum.Ver && + this.settings.Common.DispLatestPost != MyCommon.DispTitleEnum.OwnStatus) { foreach (var tab in this.statuses.Tabs) { @@ -8235,10 +8236,10 @@ private void SetMainWindowTitle() } } - if (SettingManager.Common.DispUsername) ttl.Append(this.tw.Username).Append(" - "); + if (this.settings.Common.DispUsername) ttl.Append(this.tw.Username).Append(" - "); ttl.Append(ApplicationSettings.ApplicationName); ttl.Append(" "); - switch (SettingManager.Common.DispLatestPost) + switch (this.settings.Common.DispLatestPost) { case MyCommon.DispTitleEnum.Ver: ttl.Append("Ver:").Append(MyCommon.GetReadableVersion()); @@ -8313,13 +8314,13 @@ private string GetStatusLabelText() var homeTab = this.statuses.HomeTab; slbl.AppendFormat(Properties.Resources.SetStatusLabelText1, tur, tal, ur, al, urat, this.postTimestamps.Count, this.favTimestamps.Count, homeTab.TweetsPerHour); - if (SettingManager.Common.TimelinePeriod == 0) + if (this.settings.Common.TimelinePeriod == 0) { slbl.Append(Properties.Resources.SetStatusLabelText2); } else { - slbl.Append(SettingManager.Common.TimelinePeriod + Properties.Resources.SetStatusLabelText3); + slbl.Append(this.settings.Common.TimelinePeriod + Properties.Resources.SetStatusLabelText3); } return slbl.ToString(); } @@ -8405,7 +8406,7 @@ private void SetNotifyIconText() // タスクトレイアイコンのツールチップテキスト書き換え // Tween [未読/@] ur.Remove(0, ur.Length); - if (SettingManager.Common.DispUsername) + if (this.settings.Common.DispUsername) { ur.Append(this.tw.Username); ur.Append(" - "); @@ -8448,7 +8449,7 @@ internal void CheckReplyTo(string statusText) // 本当にリプライ先指定すべきかどうかの判定 m = Regex.Matches(statusText, "(^|[ -/:-@[-^`{-~])(?@[a-zA-Z0-9_]+)"); - if (SettingManager.Common.UseAtIdSupplement) + if (this.settings.Common.UseAtIdSupplement) { var bCnt = this.AtIdSupl.ItemCount; foreach (Match mid in m) @@ -8490,19 +8491,19 @@ internal void CheckReplyTo(string statusText) private void TweenMain_Resize(object sender, EventArgs e) { - if (!this.initialLayout && SettingManager.Common.MinimizeToTray && this.WindowState == FormWindowState.Minimized) + if (!this.initialLayout && this.settings.Common.MinimizeToTray && this.WindowState == FormWindowState.Minimized) { this.Visible = false; } - if (this.initialLayout && SettingManager.Local != null && this.WindowState == FormWindowState.Normal && this.Visible) + if (this.initialLayout && this.settings.Local != null && this.WindowState == FormWindowState.Normal && this.Visible) { // 現在の DPI と設定保存時の DPI との比を取得する - var configScaleFactor = SettingManager.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions); + var configScaleFactor = this.settings.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions); - this.ClientSize = ScaleBy(configScaleFactor, SettingManager.Local.FormSize); + this.ClientSize = ScaleBy(configScaleFactor, this.settings.Local.FormSize); // Splitterの位置設定 - var splitterDistance = ScaleBy(configScaleFactor.Height, SettingManager.Local.SplitterDistance); + var splitterDistance = ScaleBy(configScaleFactor.Height, this.settings.Local.SplitterDistance); if (splitterDistance > this.SplitContainer1.Panel1MinSize && splitterDistance < this.SplitContainer1.Height - this.SplitContainer1.Panel2MinSize - this.SplitContainer1.SplitterWidth) { @@ -8510,10 +8511,10 @@ private void TweenMain_Resize(object sender, EventArgs e) } // 発言欄複数行 - this.StatusText.Multiline = SettingManager.Local.StatusMultiline; + this.StatusText.Multiline = this.settings.Local.StatusMultiline; if (this.StatusText.Multiline) { - var statusTextHeight = ScaleBy(configScaleFactor.Height, SettingManager.Local.StatusTextHeight); + var statusTextHeight = ScaleBy(configScaleFactor.Height, this.settings.Local.StatusTextHeight); var dis = this.SplitContainer2.Height - statusTextHeight - this.SplitContainer2.SplitterWidth; if (dis > this.SplitContainer2.Panel1MinSize && dis < this.SplitContainer2.Height - this.SplitContainer2.Panel2MinSize - this.SplitContainer2.SplitterWidth) { @@ -8529,7 +8530,7 @@ private void TweenMain_Resize(object sender, EventArgs e) } } - var previewDistance = ScaleBy(configScaleFactor.Width, SettingManager.Local.PreviewDistance); + var previewDistance = ScaleBy(configScaleFactor.Width, this.settings.Local.PreviewDistance); if (previewDistance > this.SplitContainer3.Panel1MinSize && previewDistance < this.SplitContainer3.Width - this.SplitContainer3.Panel2MinSize - this.SplitContainer3.SplitterWidth) { this.SplitContainer3.SplitterDistance = previewDistance; @@ -8552,11 +8553,11 @@ private void PlaySoundMenuItem_CheckedChanged(object sender, EventArgs e) this.PlaySoundFileMenuItem.Checked = this.PlaySoundMenuItem.Checked; if (this.PlaySoundMenuItem.Checked) { - SettingManager.Common.PlaySound = true; + this.settings.Common.PlaySound = true; } else { - SettingManager.Common.PlaySound = false; + this.settings.Common.PlaySound = false; } this.MarkSettingCommonModified(); } @@ -8626,7 +8627,7 @@ private void SplitContainer2_Panel2_Resize(object sender, EventArgs e) if (multiline != this.StatusText.Multiline) { this.StatusText.Multiline = multiline; - SettingManager.Local.StatusMultiline = multiline; + this.settings.Local.StatusMultiline = multiline; this.MarkSettingLocalModified(); } } @@ -8647,7 +8648,7 @@ private void MultiLineMenuItem_Click(object sender, EventArgs e) // 発言欄複数行 var menuItemChecked = ((ToolStripMenuItem)sender).Checked; this.StatusText.Multiline = menuItemChecked; - SettingManager.Local.StatusMultiline = menuItemChecked; + this.settings.Local.StatusMultiline = menuItemChecked; if (menuItemChecked) { if (this.SplitContainer2.Height - this.mySpDis2 - this.SplitContainer2.SplitterWidth < 0) @@ -8667,8 +8668,8 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) if (converterType == MyCommon.UrlConverter.Bitly || converterType == MyCommon.UrlConverter.Jmp) { // OAuth2 アクセストークンまたは API キー (旧方式) のいずれも設定されていなければ短縮しない - if (MyCommon.IsNullOrEmpty(SettingManager.Common.BitlyAccessToken) && - (MyCommon.IsNullOrEmpty(SettingManager.Common.BilyUser) || MyCommon.IsNullOrEmpty(SettingManager.Common.BitlyPwd))) + if (MyCommon.IsNullOrEmpty(this.settings.Common.BitlyAccessToken) && + (MyCommon.IsNullOrEmpty(this.settings.Common.BilyUser) || MyCommon.IsNullOrEmpty(this.settings.Common.BitlyPwd))) { MessageBox.Show(this, Properties.Resources.UrlConvert_BitlyAuthRequired, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; @@ -8692,7 +8693,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) // 文字列が選択されている場合はその文字列について処理 // nico.ms使用、nicovideoにマッチしたら変換 - if (SettingManager.Common.Nicoms && Regex.IsMatch(tmp, nico)) + if (this.settings.Common.Nicoms && Regex.IsMatch(tmp, nico)) { result = Nicoms.Shorten(tmp); } @@ -8768,7 +8769,7 @@ private async Task UrlConvertAsync(MyCommon.UrlConverter converterType) this.StatusText.Select(this.StatusText.Text.IndexOf(mt.Result("${url}"), StringComparison.Ordinal), mt.Result("${url}").Length); // nico.ms使用、nicovideoにマッチしたら変換 - if (SettingManager.Common.Nicoms && Regex.IsMatch(tmp, nico)) + if (this.settings.Common.Nicoms && Regex.IsMatch(tmp, nico)) { result = Nicoms.Shorten(tmp); } @@ -8864,7 +8865,7 @@ private async void UxnuMenuItem_Click(object sender, EventArgs e) private async void UrlConvertAutoToolStripMenuItem_Click(object sender, EventArgs e) { - if (!await this.UrlConvertAsync(SettingManager.Common.AutoShortUrlFirst)) + if (!await this.UrlConvertAsync(this.settings.Common.AutoShortUrlFirst)) { var rnd = new Random(); @@ -8874,7 +8875,7 @@ private async void UrlConvertAutoToolStripMenuItem_Click(object sender, EventArg { svc = (MyCommon.UrlConverter)rnd.Next(System.Enum.GetNames(typeof(MyCommon.UrlConverter)).Length); } - while (svc == SettingManager.Common.AutoShortUrlFirst || svc == MyCommon.UrlConverter.Nicoms || svc == MyCommon.UrlConverter.Unu); + while (svc == this.settings.Common.AutoShortUrlFirst || svc == MyCommon.UrlConverter.Nicoms || svc == MyCommon.UrlConverter.Unu); await this.UrlConvertAsync(svc); } } @@ -8886,7 +8887,7 @@ private void NewPostPopMenuItem_CheckStateChanged(object sender, EventArgs e) { this.NotifyFileMenuItem.Checked = ((ToolStripMenuItem)sender).Checked; this.NewPostPopMenuItem.Checked = this.NotifyFileMenuItem.Checked; - SettingManager.Common.NewAllPop = this.NewPostPopMenuItem.Checked; + this.settings.Common.NewAllPop = this.NewPostPopMenuItem.Checked; this.MarkSettingCommonModified(); } @@ -8894,7 +8895,7 @@ private void ListLockMenuItem_CheckStateChanged(object sender, EventArgs e) { this.ListLockMenuItem.Checked = ((ToolStripMenuItem)sender).Checked; this.LockListFileMenuItem.Checked = this.ListLockMenuItem.Checked; - SettingManager.Common.ListLock = this.ListLockMenuItem.Checked; + this.settings.Common.ListLock = this.ListLockMenuItem.Checked; this.MarkSettingCommonModified(); } @@ -8927,12 +8928,12 @@ private void MenuStrip1_MenuDeactivate(object sender, EventArgs e) private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e) { var lst = (DetailsListView)sender; - if (SettingManager.Local == null) return; + if (this.settings.Local == null) return; if (this.iconCol) { - SettingManager.Local.Width1 = lst.Columns[0].Width; - SettingManager.Local.Width3 = lst.Columns[1].Width; + this.settings.Local.Width1 = lst.Columns[0].Width; + this.settings.Local.Width3 = lst.Columns[1].Width; } else { @@ -8948,39 +8949,39 @@ private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e) switch (darr[i]) { case 0: - SettingManager.Local.DisplayIndex1 = i; + this.settings.Local.DisplayIndex1 = i; break; case 1: - SettingManager.Local.DisplayIndex2 = i; + this.settings.Local.DisplayIndex2 = i; break; case 2: - SettingManager.Local.DisplayIndex3 = i; + this.settings.Local.DisplayIndex3 = i; break; case 3: - SettingManager.Local.DisplayIndex4 = i; + this.settings.Local.DisplayIndex4 = i; break; case 4: - SettingManager.Local.DisplayIndex5 = i; + this.settings.Local.DisplayIndex5 = i; break; case 5: - SettingManager.Local.DisplayIndex6 = i; + this.settings.Local.DisplayIndex6 = i; break; case 6: - SettingManager.Local.DisplayIndex7 = i; + this.settings.Local.DisplayIndex7 = i; break; case 7: - SettingManager.Local.DisplayIndex8 = i; + this.settings.Local.DisplayIndex8 = i; break; } } - SettingManager.Local.Width1 = lst.Columns[0].Width; - SettingManager.Local.Width2 = lst.Columns[1].Width; - SettingManager.Local.Width3 = lst.Columns[2].Width; - SettingManager.Local.Width4 = lst.Columns[3].Width; - SettingManager.Local.Width5 = lst.Columns[4].Width; - SettingManager.Local.Width6 = lst.Columns[5].Width; - SettingManager.Local.Width7 = lst.Columns[6].Width; - SettingManager.Local.Width8 = lst.Columns[7].Width; + this.settings.Local.Width1 = lst.Columns[0].Width; + this.settings.Local.Width2 = lst.Columns[1].Width; + this.settings.Local.Width3 = lst.Columns[2].Width; + this.settings.Local.Width4 = lst.Columns[3].Width; + this.settings.Local.Width5 = lst.Columns[4].Width; + this.settings.Local.Width6 = lst.Columns[5].Width; + this.settings.Local.Width7 = lst.Columns[6].Width; + this.settings.Local.Width8 = lst.Columns[7].Width; } this.MarkSettingLocalModified(); this.isColumnChanged = true; @@ -8989,62 +8990,62 @@ private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e) private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e) { var lst = (DetailsListView)sender; - if (SettingManager.Local == null) return; + if (this.settings.Local == null) return; var modified = false; if (this.iconCol) { - if (SettingManager.Local.Width1 != lst.Columns[0].Width) + if (this.settings.Local.Width1 != lst.Columns[0].Width) { - SettingManager.Local.Width1 = lst.Columns[0].Width; + this.settings.Local.Width1 = lst.Columns[0].Width; modified = true; } - if (SettingManager.Local.Width3 != lst.Columns[1].Width) + if (this.settings.Local.Width3 != lst.Columns[1].Width) { - SettingManager.Local.Width3 = lst.Columns[1].Width; + this.settings.Local.Width3 = lst.Columns[1].Width; modified = true; } } else { - if (SettingManager.Local.Width1 != lst.Columns[0].Width) + if (this.settings.Local.Width1 != lst.Columns[0].Width) { - SettingManager.Local.Width1 = lst.Columns[0].Width; + this.settings.Local.Width1 = lst.Columns[0].Width; modified = true; } - if (SettingManager.Local.Width2 != lst.Columns[1].Width) + if (this.settings.Local.Width2 != lst.Columns[1].Width) { - SettingManager.Local.Width2 = lst.Columns[1].Width; + this.settings.Local.Width2 = lst.Columns[1].Width; modified = true; } - if (SettingManager.Local.Width3 != lst.Columns[2].Width) + if (this.settings.Local.Width3 != lst.Columns[2].Width) { - SettingManager.Local.Width3 = lst.Columns[2].Width; + this.settings.Local.Width3 = lst.Columns[2].Width; modified = true; } - if (SettingManager.Local.Width4 != lst.Columns[3].Width) + if (this.settings.Local.Width4 != lst.Columns[3].Width) { - SettingManager.Local.Width4 = lst.Columns[3].Width; + this.settings.Local.Width4 = lst.Columns[3].Width; modified = true; } - if (SettingManager.Local.Width5 != lst.Columns[4].Width) + if (this.settings.Local.Width5 != lst.Columns[4].Width) { - SettingManager.Local.Width5 = lst.Columns[4].Width; + this.settings.Local.Width5 = lst.Columns[4].Width; modified = true; } - if (SettingManager.Local.Width6 != lst.Columns[5].Width) + if (this.settings.Local.Width6 != lst.Columns[5].Width) { - SettingManager.Local.Width6 = lst.Columns[5].Width; + this.settings.Local.Width6 = lst.Columns[5].Width; modified = true; } - if (SettingManager.Local.Width7 != lst.Columns[6].Width) + if (this.settings.Local.Width7 != lst.Columns[6].Width) { - SettingManager.Local.Width7 = lst.Columns[6].Width; + this.settings.Local.Width7 = lst.Columns[6].Width; modified = true; } - if (SettingManager.Local.Width8 != lst.Columns[7].Width) + if (this.settings.Local.Width8 != lst.Columns[7].Width) { - SettingManager.Local.Width8 = lst.Columns[7].Width; + this.settings.Local.Width8 = lst.Columns[7].Width; modified = true; } } @@ -9212,8 +9213,8 @@ public async Task OpenUriAsync(Uri uri, bool isReverseSettings = false) // ユーザープロフィールURL // フラグが立っている場合は設定と逆の動作をする - if (SettingManager.Common.OpenUserTimeline && !isReverseSettings || - !SettingManager.Common.OpenUserTimeline && isReverseSettings) + if (this.settings.Common.OpenUserTimeline && !isReverseSettings || + !this.settings.Common.OpenUserTimeline && isReverseSettings) { var userUriMatch = Regex.Match(uriStr, "^https?://twitter.com/(#!/)?(?[a-zA-Z0-9_]+)$"); if (userUriMatch.Success) @@ -9351,10 +9352,10 @@ private async void TweenMain_Shown(object sender, EventArgs e) this.RefreshTabAsync(), }; - if (SettingManager.Common.StartupFollowers) + if (this.settings.Common.StartupFollowers) loadTasks.Add(this.RefreshFollowerIdsAsync()); - if (SettingManager.Common.GetFav) + if (this.settings.Common.GetFav) loadTasks.Add(this.RefreshTabAsync()); var allTasks = Task.WhenAll(loadTasks); @@ -9378,7 +9379,7 @@ private async void TweenMain_Shown(object sender, EventArgs e) if (ApplicationSettings.VersionInfoUrl != null) { // バージョンチェック(引数:起動時チェックの場合はtrue・・・チェック結果のメッセージを表示しない) - if (SettingManager.Common.StartupVersion) + if (this.settings.Common.StartupVersion) await this.CheckNewVersion(true); } else @@ -9399,7 +9400,7 @@ private async void TweenMain_Shown(object sender, EventArgs e) // 取得失敗の場合は再試行する var reloadTasks = new List(); - if (!this.tw.GetFollowersSuccess && SettingManager.Common.StartupFollowers) + if (!this.tw.GetFollowersSuccess && this.settings.Common.StartupFollowers) reloadTasks.Add(this.RefreshFollowerIdsAsync()); if (!this.tw.GetNoRetweetSuccess) @@ -9464,7 +9465,7 @@ private async Task DoReTweetOfficial(bool isConfirm) } else { - if (!SettingManager.Common.RetweetNoConfirm) + if (!this.settings.Common.RetweetNoConfirm) { var questiontext = Properties.Resources.RetweetQuestion1; if (this.doFavRetweetFlags) questiontext = Properties.Resources.FavoritesRetweetQuestionText2; @@ -9575,17 +9576,17 @@ private void PreventSmsCommandMenuItem_CheckedChanged(object sender, EventArgs e => this.preventSmsCommand = ((ToolStripMenuItem)sender).Checked; private void UrlAutoShortenMenuItem_CheckedChanged(object sender, EventArgs e) - => SettingManager.Common.UrlConvertAuto = ((ToolStripMenuItem)sender).Checked; + => this.settings.Common.UrlConvertAuto = ((ToolStripMenuItem)sender).Checked; private void IdeographicSpaceToSpaceMenuItem_Click(object sender, EventArgs e) { - SettingManager.Common.WideSpaceConvert = ((ToolStripMenuItem)sender).Checked; + this.settings.Common.WideSpaceConvert = ((ToolStripMenuItem)sender).Checked; this.MarkSettingCommonModified(); } private void FocusLockMenuItem_CheckedChanged(object sender, EventArgs e) { - SettingManager.Common.FocusLockToStatusText = ((ToolStripMenuItem)sender).Checked; + this.settings.Common.FocusLockToStatusText = ((ToolStripMenuItem)sender).Checked; this.MarkSettingCommonModified(); } @@ -9593,20 +9594,20 @@ private void PostModeMenuItem_DropDownOpening(object sender, EventArgs e) { this.UrlMultibyteSplitMenuItem.Checked = this.urlMultibyteSplit; this.PreventSmsCommandMenuItem.Checked = this.preventSmsCommand; - this.UrlAutoShortenMenuItem.Checked = SettingManager.Common.UrlConvertAuto; - this.IdeographicSpaceToSpaceMenuItem.Checked = SettingManager.Common.WideSpaceConvert; - this.MultiLineMenuItem.Checked = SettingManager.Local.StatusMultiline; - this.FocusLockMenuItem.Checked = SettingManager.Common.FocusLockToStatusText; + this.UrlAutoShortenMenuItem.Checked = this.settings.Common.UrlConvertAuto; + this.IdeographicSpaceToSpaceMenuItem.Checked = this.settings.Common.WideSpaceConvert; + this.MultiLineMenuItem.Checked = this.settings.Local.StatusMultiline; + this.FocusLockMenuItem.Checked = this.settings.Common.FocusLockToStatusText; } private void ContextMenuPostMode_Opening(object sender, CancelEventArgs e) { this.UrlMultibyteSplitPullDownMenuItem.Checked = this.urlMultibyteSplit; this.PreventSmsCommandPullDownMenuItem.Checked = this.preventSmsCommand; - this.UrlAutoShortenPullDownMenuItem.Checked = SettingManager.Common.UrlConvertAuto; - this.IdeographicSpaceToSpacePullDownMenuItem.Checked = SettingManager.Common.WideSpaceConvert; - this.MultiLinePullDownMenuItem.Checked = SettingManager.Local.StatusMultiline; - this.FocusLockPullDownMenuItem.Checked = SettingManager.Common.FocusLockToStatusText; + this.UrlAutoShortenPullDownMenuItem.Checked = this.settings.Common.UrlConvertAuto; + this.IdeographicSpaceToSpacePullDownMenuItem.Checked = this.settings.Common.WideSpaceConvert; + this.MultiLinePullDownMenuItem.Checked = this.settings.Local.StatusMultiline; + this.FocusLockPullDownMenuItem.Checked = this.settings.Common.FocusLockToStatusText; } private void TraceOutToolStripMenuItem_Click(object sender, EventArgs e) @@ -10189,7 +10190,7 @@ private void HashManageMenuItem_Click(object sender, EventArgs e) { return; } - this.TopMost = SettingManager.Common.AlwaysTop; + this.TopMost = this.settings.Common.AlwaysTop; if (rslt == DialogResult.Cancel) return; if (!MyCommon.IsNullOrEmpty(this.HashMgr.UseHash)) { @@ -10900,14 +10901,14 @@ private void StopRefreshAllMenuItem_CheckedChanged(object sender, EventArgs e) private async Task OpenUserAppointUrl() { - if (SettingManager.Common.UserAppointUrl != null) + if (this.settings.Common.UserAppointUrl != null) { - if (SettingManager.Common.UserAppointUrl.Contains("{ID}") || SettingManager.Common.UserAppointUrl.Contains("{STATUS}")) + if (this.settings.Common.UserAppointUrl.Contains("{ID}") || this.settings.Common.UserAppointUrl.Contains("{STATUS}")) { var post = this.CurrentPost; if (post != null) { - var xUrl = SettingManager.Common.UserAppointUrl; + var xUrl = this.settings.Common.UserAppointUrl; xUrl = xUrl.Replace("{ID}", post.ScreenName); var statusId = post.RetweetedId ?? post.StatusId; @@ -10918,7 +10919,7 @@ private async Task OpenUserAppointUrl() } else { - await MyCommon.OpenInBrowserAsync(this, SettingManager.Common.UserAppointUrl); + await MyCommon.OpenInBrowserAsync(this, this.settings.Common.UserAppointUrl); } } } @@ -10985,13 +10986,13 @@ private void PostButton_KeyDown(object sender, KeyEventArgs e) private void ContextMenuColumnHeader_Opening(object sender, CancelEventArgs e) { - this.IconSizeNoneToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.IconNone; - this.IconSize16ToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.Icon16; - this.IconSize24ToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.Icon24; - this.IconSize48ToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.Icon48; - this.IconSize48_2ToolStripMenuItem.Checked = SettingManager.Common.IconSize == MyCommon.IconSizes.Icon48_2; + this.IconSizeNoneToolStripMenuItem.Checked = this.settings.Common.IconSize == MyCommon.IconSizes.IconNone; + this.IconSize16ToolStripMenuItem.Checked = this.settings.Common.IconSize == MyCommon.IconSizes.Icon16; + this.IconSize24ToolStripMenuItem.Checked = this.settings.Common.IconSize == MyCommon.IconSizes.Icon24; + this.IconSize48ToolStripMenuItem.Checked = this.settings.Common.IconSize == MyCommon.IconSizes.Icon48; + this.IconSize48_2ToolStripMenuItem.Checked = this.settings.Common.IconSize == MyCommon.IconSizes.Icon48_2; - this.LockListSortOrderToolStripMenuItem.Checked = SettingManager.Common.SortOrderLock; + this.LockListSortOrderToolStripMenuItem.Checked = this.settings.Common.SortOrderLock; } private void IconSizeNoneToolStripMenuItem_Click(object sender, EventArgs e) @@ -11011,11 +11012,11 @@ private void IconSize48_2ToolStripMenuItem_Click(object sender, EventArgs e) private void ChangeListViewIconSize(MyCommon.IconSizes iconSize) { - if (SettingManager.Common.IconSize == iconSize) return; + if (this.settings.Common.IconSize == iconSize) return; var oldIconCol = this.iconCol; - SettingManager.Common.IconSize = iconSize; + this.settings.Common.IconSize = iconSize; this.ApplyListViewIconSize(iconSize); if (this.iconCol != oldIconCol) @@ -11033,9 +11034,9 @@ private void ChangeListViewIconSize(MyCommon.IconSizes iconSize) private void LockListSortToolStripMenuItem_Click(object sender, EventArgs e) { var state = this.LockListSortOrderToolStripMenuItem.Checked; - if (SettingManager.Common.SortOrderLock == state) return; + if (this.settings.Common.SortOrderLock == state) return; - SettingManager.Common.SortOrderLock = state; + this.settings.Common.SortOrderLock = state; this.MarkSettingCommonModified(); } diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 8a3e0d3bf..ccbb9f163 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -128,12 +128,12 @@ public async Task ShowPostDetails(PostClass post) } var nameForeColor = SystemColors.ControlText; - if (post.IsOwl && (SettingManager.Common.OneWayLove || post.IsDm)) - nameForeColor = SettingManager.Local.ColorOWL; + if (post.IsOwl && (SettingManager.Instance.Common.OneWayLove || post.IsDm)) + nameForeColor = SettingManager.Instance.Local.ColorOWL; if (post.RetweetedId != null) - nameForeColor = SettingManager.Local.ColorRetweet; + nameForeColor = SettingManager.Instance.Local.ColorRetweet; if (post.IsFav) - nameForeColor = SettingManager.Local.ColorFav; + nameForeColor = SettingManager.Instance.Local.ColorFav; this.AuthorNameLinkLabel.LinkColor = nameForeColor; this.AuthorNameLinkLabel.ActiveLinkColor = nameForeColor; @@ -219,9 +219,9 @@ public void ScrollDownPostBrowser(bool forward) if (tags.Count > 0) { if (forward) - tags[0].ScrollTop += SettingManager.Local.FontDetail.Height; + tags[0].ScrollTop += SettingManager.Instance.Local.FontDetail.Height; else - tags[0].ScrollTop -= SettingManager.Local.FontDetail.Height; + tags[0].ScrollTop -= SettingManager.Instance.Local.FontDetail.Height; } } @@ -234,9 +234,9 @@ public void PageDownPostBrowser(bool forward) if (tags.Count > 0) { if (forward) - tags[0].ScrollTop += this.PostBrowser.ClientRectangle.Height - SettingManager.Local.FontDetail.Height; + tags[0].ScrollTop += this.PostBrowser.ClientRectangle.Height - SettingManager.Instance.Local.FontDetail.Height; else - tags[0].ScrollTop -= this.PostBrowser.ClientRectangle.Height - SettingManager.Local.FontDetail.Height; + tags[0].ScrollTop -= this.PostBrowser.ClientRectangle.Height - SettingManager.Instance.Local.FontDetail.Height; } } @@ -405,7 +405,7 @@ private async Task DoTranslation(string str) { var translatedText = await bing.TranslateAsync(str, langFrom: null, - langTo: SettingManager.Common.TranslateLanguage); + langTo: SettingManager.Instance.Common.TranslateLanguage); this.PostBrowser.DocumentText = this.Owner.CreateDetailHtml(translatedText); } diff --git a/OpenTween/TweetFormatter.cs b/OpenTween/TweetFormatter.cs index 681ecd53e..6cb8cf389 100644 --- a/OpenTween/TweetFormatter.cs +++ b/OpenTween/TweetFormatter.cs @@ -167,7 +167,7 @@ private static string FormatMentionEntity(string targetText, TwitterEntityMentio private static string FormatEmojiEntity(string targetText, TwitterEntityEmoji entity) { - if (!SettingManager.Local.UseTwemoji) + if (!SettingManager.Instance.Local.UseTwemoji) return T(E(targetText)); if (MyCommon.IsNullOrEmpty(entity.Url)) diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index d90efd163..9bf1cbc81 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -501,42 +501,42 @@ public static int GetMaxApiResultCount(MyCommon.WORKERTYPE type) /// public static int GetApiResultCount(MyCommon.WORKERTYPE type, bool more, bool startup) { - if (SettingManager.Common.UseAdditionalCount) + if (SettingManager.Instance.Common.UseAdditionalCount) { switch (type) { case MyCommon.WORKERTYPE.Favorites: - if (SettingManager.Common.FavoritesCountApi != 0) - return SettingManager.Common.FavoritesCountApi; + if (SettingManager.Instance.Common.FavoritesCountApi != 0) + return SettingManager.Instance.Common.FavoritesCountApi; break; case MyCommon.WORKERTYPE.List: - if (SettingManager.Common.ListCountApi != 0) - return SettingManager.Common.ListCountApi; + if (SettingManager.Instance.Common.ListCountApi != 0) + return SettingManager.Instance.Common.ListCountApi; break; case MyCommon.WORKERTYPE.PublicSearch: - if (SettingManager.Common.SearchCountApi != 0) - return SettingManager.Common.SearchCountApi; + if (SettingManager.Instance.Common.SearchCountApi != 0) + return SettingManager.Instance.Common.SearchCountApi; break; case MyCommon.WORKERTYPE.UserTimeline: - if (SettingManager.Common.UserTimelineCountApi != 0) - return SettingManager.Common.UserTimelineCountApi; + if (SettingManager.Instance.Common.UserTimelineCountApi != 0) + return SettingManager.Instance.Common.UserTimelineCountApi; break; } - if (more && SettingManager.Common.MoreCountApi != 0) + if (more && SettingManager.Instance.Common.MoreCountApi != 0) { - return Math.Min(SettingManager.Common.MoreCountApi, GetMaxApiResultCount(type)); + return Math.Min(SettingManager.Instance.Common.MoreCountApi, GetMaxApiResultCount(type)); } - if (startup && SettingManager.Common.FirstCountApi != 0 && type != MyCommon.WORKERTYPE.Reply) + if (startup && SettingManager.Instance.Common.FirstCountApi != 0 && type != MyCommon.WORKERTYPE.Reply) { - return Math.Min(SettingManager.Common.FirstCountApi, GetMaxApiResultCount(type)); + return Math.Min(SettingManager.Instance.Common.FirstCountApi, GetMaxApiResultCount(type)); } } // 上記に当てはまらない場合の共通処理 - var count = SettingManager.Common.CountApi; + var count = SettingManager.Instance.Common.CountApi; if (type == MyCommon.WORKERTYPE.Reply) - count = SettingManager.Common.CountApiReply; + count = SettingManager.Instance.Common.CountApiReply; return Math.Min(count, GetMaxApiResultCount(type)); } @@ -951,12 +951,12 @@ public async Task GetListStatus(bool read, ListTimelineTabModel tab, bool more, TwitterStatus[] statuses; if (more) { - statuses = await this.Api.ListsStatuses(tab.ListInfo.Id, count, maxId: tab.OldestId, includeRTs: SettingManager.Common.IsListsIncludeRts) + statuses = await this.Api.ListsStatuses(tab.ListInfo.Id, count, maxId: tab.OldestId, includeRTs: SettingManager.Instance.Common.IsListsIncludeRts) .ConfigureAwait(false); } else { - statuses = await this.Api.ListsStatuses(tab.ListInfo.Id, count, includeRTs: SettingManager.Common.IsListsIncludeRts) + statuses = await this.Api.ListsStatuses(tab.ListInfo.Id, count, includeRTs: SettingManager.Instance.Common.IsListsIncludeRts) .ConfigureAwait(false); } From 79883965825d663295bd2b36d1f576d382f696f8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 07:14:55 +0900 Subject: [PATCH 155/402] =?UTF-8?q?=E8=B5=B7=E5=8B=95=E6=99=82=E3=81=AE?= =?UTF-8?q?=E4=BE=9D=E5=AD=98=E9=96=A2=E4=BF=82=E3=82=92=E8=A7=A3=E6=B1=BA?= =?UTF-8?q?=E3=81=99=E3=82=8BApplicationContainer=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationContainer.cs | 65 +++++++++++++++++++++++++++++++ OpenTween/ApplicationEvents.cs | 7 ++-- OpenTween/OpenTween.csproj | 1 + 3 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 OpenTween/ApplicationContainer.cs diff --git a/OpenTween/ApplicationContainer.cs b/OpenTween/ApplicationContainer.cs new file mode 100644 index 000000000..5fa8772c3 --- /dev/null +++ b/OpenTween/ApplicationContainer.cs @@ -0,0 +1,65 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using OpenTween.Setting; + +namespace OpenTween +{ + public sealed class ApplicationContainer : IDisposable + { + public bool IsDisposed { get; private set; } = false; + + public SettingManager Settings { get; } = SettingManager.Instance; + + public CultureService CultureService + => this.cultureServiceLazy.Value; + + public TweenMain MainForm + => this.mainFormLazy.Value; + + private readonly Lazy cultureServiceLazy; + private readonly Lazy mainFormLazy; + + public ApplicationContainer() + { + this.cultureServiceLazy = new(this.CreateCultureService); + this.mainFormLazy = new(this.CreateTweenMain); + } + + private CultureService CreateCultureService() + => new(this.Settings.Common); + + private TweenMain CreateTweenMain() + => new(); + + public void Dispose() + { + if (this.IsDisposed) + return; + + this.IsDisposed = true; + this.MainForm.Dispose(); + } + } +} diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 81d31566e..80cc1e16a 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -62,8 +62,9 @@ public static int Main(string[] args) SettingManager.Instance.LoadAll(); - var cultureService = new CultureService(SettingManager.Instance.Common); - cultureService.Initialize(); + using var container = new ApplicationContainer(); + + container.CultureService.Initialize(); // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する using var mutex = new ApplicationInstanceMutex(ApplicationSettings.AssemblyName, MyCommon.SettingPath); @@ -77,7 +78,7 @@ public static int Main(string[] args) return 1; } - Application.Run(new TweenMain()); + Application.Run(container.MainForm); return 0; } diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 7364c29fd..d85932a01 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -100,6 +100,7 @@ + Code From 8f818248e22d7d93496b667e62192d8f495ad257 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 07:34:08 +0900 Subject: [PATCH 156/402] =?UTF-8?q?TweenMain=5FLoad=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=81=AE=E5=87=A6=E7=90=86=E3=82=92=E3=82=B3?= =?UTF-8?q?=E3=83=B3=E3=82=B9=E3=83=88=E3=83=A9=E3=82=AF=E3=82=BF=E3=81=AB?= =?UTF-8?q?=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Tween.Designer.cs | 1 - OpenTween/Tween.cs | 79 +++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 44 deletions(-) diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index 8f12f98e9..4ffb5d8fb 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -2128,7 +2128,6 @@ private void InitializeComponent() this.Activated += new System.EventHandler(this.TweenMain_Activated); this.Deactivate += new System.EventHandler(this.TweenMain_Deactivate); this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.TweenMain_FormClosing); - this.Load += new System.EventHandler(this.TweenMain_Load); this.Shown += new System.EventHandler(this.TweenMain_Shown); this.ClientSizeChanged += new System.EventHandler(this.TweenMain_ClientSizeChanged); this.LocationChanged += new System.EventHandler(this.TweenMain_LocationChanged); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 566156dc3..a0706f873 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -137,7 +137,7 @@ public partial class TweenMain : OTBaseForm // twitter解析部 private readonly TwitterApi twitterApi = new(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); - private Twitter tw = null!; + private readonly Twitter tw; // Growl呼び出し部 private readonly GrowlHelper gh = new(ApplicationSettings.ApplicationName); @@ -226,7 +226,7 @@ public partial class TweenMain : OTBaseForm private Font fntInputFont = null!; /// アイコン画像リスト - private ImageCache iconCache = null!; + private readonly ImageCache iconCache; /// タスクトレイアイコン:通常時 (At.ico) private Icon nIconAt = null!; @@ -285,7 +285,7 @@ public partial class TweenMain : OTBaseForm private readonly StringFormat sfTab = new(); ////////////////////////////////////////////////////////////////////////////////////////////////////////// - private TabInformations statuses = null!; + private readonly TabInformations statuses; /// /// 現在表示している発言一覧の に対するキャッシュ @@ -358,10 +358,10 @@ public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [ ////////////////////////////////////////////////////////////////////////////////////////////////////////// private readonly TimelineScheduler timelineScheduler = new(); - private DebounceTimer selectionDebouncer = null!; - private DebounceTimer saveConfigDebouncer = null!; + private readonly DebounceTimer selectionDebouncer; + private readonly DebounceTimer saveConfigDebouncer; - private string recommendedStatusFooter = null!; + private readonly string recommendedStatusFooter; private bool urlMultibyteSplit = false; private bool preventSmsCommand = true; @@ -413,6 +413,8 @@ private readonly record struct StatusTextHistory( (long StatusId, string ScreenName)? InReplyTo = null ); + private readonly HookGlobalHotkey hookGlobalHotkey; + private void TweenMain_Activated(object sender, EventArgs e) { // 画面がアクティブになったら、発言欄の背景色戻す @@ -756,8 +758,35 @@ private void InitializeTraceFrag() } } - private void TweenMain_Load(object sender, EventArgs e) + public TweenMain() { + this.InitializeComponent(); + + if (!this.DesignMode) + { + // デザイナでの編集時にレイアウトが縦方向に数pxずれる問題の対策 + this.StatusText.Dock = DockStyle.Fill; + } + + this.hookGlobalHotkey = new HookGlobalHotkey(this); + + this.tweetDetailsView.Owner = this; + + this.hookGlobalHotkey.HotkeyPressed += this.HookGlobalHotkey_HotkeyPressed; + this.gh.NotifyClicked += this.GrowlHelper_Callback; + + // メイリオフォント指定時にタブの最小幅が広くなる問題の対策 + this.ListTab.HandleCreated += (s, e) => NativeMethods.SetMinTabWidth((TabControl)s, 40); + + this.ImageSelector.Visible = false; + this.ImageSelector.Enabled = false; + this.ImageSelector.FilePickDialog = this.OpenFileDialog1; + + this.workerProgress = new Progress(x => this.StatusLabel.Text = x); + + this.ReplaceAppName(); + this.InitializeShortcuts(); + this.ignoreConfigSave = true; this.Visible = false; @@ -864,7 +893,6 @@ private void TweenMain_Load(object sender, EventArgs e) MyCommon.IsNullOrEmpty(this.tw.Username)) { Application.Exit(); // 強制終了 - return; } } @@ -10516,41 +10544,6 @@ private async void RtCountMenuItem_Click(object sender, EventArgs e) MessageBox.Show(status.RetweetCount + Properties.Resources.RtCountText1); } - private readonly HookGlobalHotkey hookGlobalHotkey; - - public TweenMain() - { - this.hookGlobalHotkey = new HookGlobalHotkey(this); - - // この呼び出しは、Windows フォーム デザイナで必要です。 - this.InitializeComponent(); - - // InitializeComponent() 呼び出しの後で初期化を追加します。 - - if (!this.DesignMode) - { - // デザイナでの編集時にレイアウトが縦方向に数pxずれる問題の対策 - this.StatusText.Dock = DockStyle.Fill; - } - - this.tweetDetailsView.Owner = this; - - this.hookGlobalHotkey.HotkeyPressed += this.HookGlobalHotkey_HotkeyPressed; - this.gh.NotifyClicked += this.GrowlHelper_Callback; - - // メイリオフォント指定時にタブの最小幅が広くなる問題の対策 - this.ListTab.HandleCreated += (s, e) => NativeMethods.SetMinTabWidth((TabControl)s, 40); - - this.ImageSelector.Visible = false; - this.ImageSelector.Enabled = false; - this.ImageSelector.FilePickDialog = this.OpenFileDialog1; - - this.workerProgress = new Progress(x => this.StatusLabel.Text = x); - - this.ReplaceAppName(); - this.InitializeShortcuts(); - } - private void HookGlobalHotkey_HotkeyPressed(object sender, KeyEventArgs e) { if ((this.WindowState == FormWindowState.Normal || this.WindowState == FormWindowState.Maximized) && this.Visible && Form.ActiveForm == this) From 51499eb83e40c41395e73bd4d42289be18bdf786 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 08:17:49 +0900 Subject: [PATCH 157/402] =?UTF-8?q?SettingManager,=20TabInformations=20?= =?UTF-8?q?=E3=81=AE=E5=88=9D=E6=9C=9F=E5=8C=96=E3=82=92TweenMain=E3=81=AE?= =?UTF-8?q?=E5=A4=96=E3=81=B8=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationContainer.cs | 5 ++++- OpenTween/Tween.cs | 12 +++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/OpenTween/ApplicationContainer.cs b/OpenTween/ApplicationContainer.cs index 5fa8772c3..7902f252b 100644 --- a/OpenTween/ApplicationContainer.cs +++ b/OpenTween/ApplicationContainer.cs @@ -22,6 +22,7 @@ #nullable enable using System; +using OpenTween.Models; using OpenTween.Setting; namespace OpenTween @@ -32,6 +33,8 @@ public sealed class ApplicationContainer : IDisposable public SettingManager Settings { get; } = SettingManager.Instance; + public TabInformations TabInfo { get; } = TabInformations.GetInstance(); + public CultureService CultureService => this.cultureServiceLazy.Value; @@ -51,7 +54,7 @@ private CultureService CreateCultureService() => new(this.Settings.Common); private TweenMain CreateTweenMain() - => new(); + => new(this.Settings, this.TabInfo); public void Dispose() { diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index a0706f873..bc391e266 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -133,7 +133,7 @@ public partial class TweenMain : OTBaseForm private FormWindowState formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する // 設定ファイル - private readonly SettingManager settings = SettingManager.Instance; + private readonly SettingManager settings; // twitter解析部 private readonly TwitterApi twitterApi = new(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); @@ -285,6 +285,8 @@ public partial class TweenMain : OTBaseForm private readonly StringFormat sfTab = new(); ////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /// 発言保持クラス private readonly TabInformations statuses; /// @@ -758,8 +760,11 @@ private void InitializeTraceFrag() } } - public TweenMain() + public TweenMain(SettingManager settingManager, TabInformations tabInfo) { + this.settings = settingManager; + this.statuses = tabInfo; + this.InitializeComponent(); if (!this.DesignMode) @@ -799,9 +804,6 @@ public TweenMain() Regex.CacheSize = 100; - // 発言保持クラス - this.statuses = TabInformations.GetInstance(); - // アイコン設定 this.LoadIcons(); this.Icon = this.mainIcon; // メインフォーム(TweenMain) From 32aa04daf2f0d3ddb9f2bb88860b85fa91fcfcf1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 09:06:05 +0900 Subject: [PATCH 158/402] =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E5=80=A4=E3=81=AE?= =?UTF-8?q?=E6=A4=9C=E8=A8=BC=E5=87=A6=E7=90=86=E3=82=92TweenMain=E3=81=AE?= =?UTF-8?q?=E5=A4=96=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 8 +++- OpenTween/Setting/SettingCommon.cs | 61 ++++++++++++++++++++++++++++++ OpenTween/Tween.cs | 55 --------------------------- 3 files changed, 67 insertions(+), 57 deletions(-) diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 80cc1e16a..b94e4ad31 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -60,10 +60,14 @@ public static int Main(string[] args) if (!SetConfigDirectoryPath()) return 1; - SettingManager.Instance.LoadAll(); - using var container = new ApplicationContainer(); + var settings = container.Settings; + settings.LoadAll(); + + var noLimit = StartupOptions.ContainsKey("nolimit"); + settings.Common.Validate(noLimit); + container.CultureService.Initialize(); // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index de6ca3ec2..0716f329c 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -260,6 +260,67 @@ public Version? SkipUpdateVersion [XmlElement(ElementName = nameof(SkipUpdateVersion))] public string SkipUpdateVersionStr { get; set; } = ""; + + public void Validate(bool noLimit = false) + { + if (!noLimit) + { + if (this.TimelinePeriod < 15 && this.TimelinePeriod > 0) + this.TimelinePeriod = 15; + + if (this.ReplyPeriod < 15 && this.ReplyPeriod > 0) + this.ReplyPeriod = 15; + + if (this.DMPeriod < 15 && this.DMPeriod > 0) + this.DMPeriod = 15; + + if (this.PubSearchPeriod < 30 && this.PubSearchPeriod > 0) + this.PubSearchPeriod = 30; + + if (this.UserTimelinePeriod < 15 && this.UserTimelinePeriod > 0) + this.UserTimelinePeriod = 15; + + if (this.ListsPeriod < 15 && this.ListsPeriod > 0) + this.ListsPeriod = 15; + } + + if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Timeline, this.CountApi)) + this.CountApi = 60; + + if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Reply, this.CountApiReply)) + this.CountApiReply = 40; + + if (this.MoreCountApi != 0 && !Twitter.VerifyMoreApiResultCount(this.MoreCountApi)) + this.MoreCountApi = 200; + + if (this.FirstCountApi != 0 && !Twitter.VerifyFirstApiResultCount(this.FirstCountApi)) + this.FirstCountApi = 100; + + if (this.FavoritesCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Favorites, this.FavoritesCountApi)) + this.FavoritesCountApi = 40; + + if (this.ListCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.List, this.ListCountApi)) + this.ListCountApi = 100; + + if (this.SearchCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.PublicSearch, this.SearchCountApi)) + this.SearchCountApi = 100; + + if (this.UserTimelineCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.UserTimeline, this.UserTimelineCountApi)) + this.UserTimelineCountApi = 20; + + // 廃止サービスが選択されていた場合ux.nuへ読み替え + if (this.AutoShortUrlFirst < 0) + this.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu; + + var selectedAccount = this.UserAccounts.Find( + x => string.Equals(x.Username, this.UserName, StringComparison.InvariantCultureIgnoreCase) + ); + if (selectedAccount?.UserId == 0) + selectedAccount.UserId = this.UserId; + + if (MyCommon.IsNullOrEmpty(this.Token)) + this.UserName = ""; + } } public class UserAccount diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index bc391e266..269c638bf 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -825,56 +825,10 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo) this.Font = fontUIGlobal; } - // 不正値チェック - if (!ApplicationEvents.StartupOptions.ContainsKey("nolimit")) - { - if (this.settings.Common.TimelinePeriod < 15 && this.settings.Common.TimelinePeriod > 0) - this.settings.Common.TimelinePeriod = 15; - - if (this.settings.Common.ReplyPeriod < 15 && this.settings.Common.ReplyPeriod > 0) - this.settings.Common.ReplyPeriod = 15; - - if (this.settings.Common.DMPeriod < 15 && this.settings.Common.DMPeriod > 0) - this.settings.Common.DMPeriod = 15; - - if (this.settings.Common.PubSearchPeriod < 30 && this.settings.Common.PubSearchPeriod > 0) - this.settings.Common.PubSearchPeriod = 30; - - if (this.settings.Common.UserTimelinePeriod < 15 && this.settings.Common.UserTimelinePeriod > 0) - this.settings.Common.UserTimelinePeriod = 15; - - if (this.settings.Common.ListsPeriod < 15 && this.settings.Common.ListsPeriod > 0) - this.settings.Common.ListsPeriod = 15; - } - - if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Timeline, this.settings.Common.CountApi)) - this.settings.Common.CountApi = 60; - if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Reply, this.settings.Common.CountApiReply)) - this.settings.Common.CountApiReply = 40; - - if (this.settings.Common.MoreCountApi != 0 && !Twitter.VerifyMoreApiResultCount(this.settings.Common.MoreCountApi)) - this.settings.Common.MoreCountApi = 200; - if (this.settings.Common.FirstCountApi != 0 && !Twitter.VerifyFirstApiResultCount(this.settings.Common.FirstCountApi)) - this.settings.Common.FirstCountApi = 100; - - if (this.settings.Common.FavoritesCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Favorites, this.settings.Common.FavoritesCountApi)) - this.settings.Common.FavoritesCountApi = 40; - if (this.settings.Common.ListCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.List, this.settings.Common.ListCountApi)) - this.settings.Common.ListCountApi = 100; - if (this.settings.Common.SearchCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.PublicSearch, this.settings.Common.SearchCountApi)) - this.settings.Common.SearchCountApi = 100; - if (this.settings.Common.UserTimelineCountApi != 0 && !Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.UserTimeline, this.settings.Common.UserTimelineCountApi)) - this.settings.Common.UserTimelineCountApi = 20; - - // 廃止サービスが選択されていた場合ux.nuへ読み替え - if (this.settings.Common.AutoShortUrlFirst < 0) - this.settings.Common.AutoShortUrlFirst = MyCommon.UrlConverter.Uxnu; - TwitterApiConnection.RestApiHost = this.settings.Common.TwitterApiHost; this.tw = new Twitter(this.twitterApi); // 認証関連 - if (MyCommon.IsNullOrEmpty(this.settings.Common.Token)) this.settings.Common.UserName = ""; this.tw.Initialize(this.settings.Common.Token, this.settings.Common.TokenSecret, this.settings.Common.UserName, this.settings.Common.UserId); this.initial = true; @@ -1199,15 +1153,6 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo) this.TweenMain_Resize(this, EventArgs.Empty); if (saveRequired) this.SaveConfigsAll(false); - foreach (var ua in this.settings.Common.UserAccounts) - { - if (ua.UserId == 0 && ua.Username.Equals(this.tw.Username, StringComparison.InvariantCultureIgnoreCase)) - { - ua.UserId = this.tw.UserId; - break; - } - } - if (firstRun) { // 初回起動時だけ右下のメニューを目立たせる From a627bbbb2f2a10e3222bd543618ab43f6bc20613 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 09:13:57 +0900 Subject: [PATCH 159/402] =?UTF-8?q?TraceFlag=E3=81=AE=E5=88=9D=E6=9C=9F?= =?UTF-8?q?=E5=8C=96=E3=82=92ApplicationEvents=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 19 +++++++++++++++++++ OpenTween/Tween.cs | 18 +----------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index b94e4ad31..c5837e678 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -53,6 +53,7 @@ public static int Main(string[] args) using var errorReportHandler = new ErrorReportHandler(); StartupOptions = new(args); + InitializeTraceFrag(); if (!ApplicationPreconditions.CheckAll()) return 1; @@ -87,6 +88,24 @@ public static int Main(string[] args) return 0; } + private static void InitializeTraceFrag() + { + var traceFlag = false; + +#if DEBUG + traceFlag = true; +#endif + + if (StartupOptions.ContainsKey("d")) + traceFlag = true; + + var version = Version.Parse(MyCommon.FileVersion); + if (version.Build != 0) + traceFlag = true; + + MyCommon.TraceFlag = traceFlag; + } + private static bool SetConfigDirectoryPath() { if (StartupOptions.TryGetValue("configDir", out var configDir) && !MyCommon.IsNullOrEmpty(configDir)) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 269c638bf..a382b1de8 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -747,19 +747,6 @@ private void InitColumnText() } } - private void InitializeTraceFrag() - { -#if DEBUG - this.TraceOutToolStripMenuItem.Checked = true; - MyCommon.TraceFlag = true; -#endif - if (!MyCommon.FileVersion.EndsWith("0", StringComparison.Ordinal)) - { - this.TraceOutToolStripMenuItem.Checked = true; - MyCommon.TraceFlag = true; - } - } - public TweenMain(SettingManager settingManager, TabInformations tabInfo) { this.settings = settingManager; @@ -795,10 +782,7 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo) this.ignoreConfigSave = true; this.Visible = false; - if (ApplicationEvents.StartupOptions.ContainsKey("d")) - MyCommon.TraceFlag = true; - - this.InitializeTraceFrag(); + this.TraceOutToolStripMenuItem.Checked = MyCommon.TraceFlag; Microsoft.Win32.SystemEvents.PowerModeChanged += this.SystemEvents_PowerModeChanged; From 1c24a06f494b72fee0f959940a6b5daa23fe2d8e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 09:32:47 +0900 Subject: [PATCH 160/402] =?UTF-8?q?Twitter=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AE=E5=88=9D=E6=9C=9F=E5=8C=96=E3=82=92ApplicationContain?= =?UTF-8?q?er=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/AppendSettingDialog.cs | 2 -- OpenTween/ApplicationContainer.cs | 21 ++++++++++++++- OpenTween/Tween.cs | 45 +++++++++++++++---------------- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index 2d48984c6..574ed8f13 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -39,7 +39,6 @@ using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; -using OpenTween.Api; using OpenTween.Connection; using OpenTween.Setting.Panel; using OpenTween.Thumbnail; @@ -51,7 +50,6 @@ public partial class AppendSettingDialog : OTBaseForm public event EventHandler? IntervalChanged; internal Twitter Tw = null!; - internal TwitterApi TwitterApi = null!; public AppendSettingDialog() { diff --git a/OpenTween/ApplicationContainer.cs b/OpenTween/ApplicationContainer.cs index 7902f252b..7de7d0067 100644 --- a/OpenTween/ApplicationContainer.cs +++ b/OpenTween/ApplicationContainer.cs @@ -22,6 +22,7 @@ #nullable enable using System; +using OpenTween.Api; using OpenTween.Models; using OpenTween.Setting; @@ -38,23 +39,39 @@ public sealed class ApplicationContainer : IDisposable public CultureService CultureService => this.cultureServiceLazy.Value; + public TwitterApi TwitterApi + => this.twitterApiLazy.Value; + + public Twitter Twitter + => this.twitterLazy.Value; + public TweenMain MainForm => this.mainFormLazy.Value; private readonly Lazy cultureServiceLazy; + private readonly Lazy twitterApiLazy; + private readonly Lazy twitterLazy; private readonly Lazy mainFormLazy; public ApplicationContainer() { this.cultureServiceLazy = new(this.CreateCultureService); + this.twitterApiLazy = new(this.CreateTwitterApi); + this.twitterLazy = new(this.CreateTwitter); this.mainFormLazy = new(this.CreateTweenMain); } private CultureService CreateCultureService() => new(this.Settings.Common); + private TwitterApi CreateTwitterApi() + => new(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); + + private Twitter CreateTwitter() + => new(this.TwitterApi); + private TweenMain CreateTweenMain() - => new(this.Settings, this.TabInfo); + => new(this.Settings, this.TabInfo, this.Twitter); public void Dispose() { @@ -63,6 +80,8 @@ public void Dispose() this.IsDisposed = true; this.MainForm.Dispose(); + this.Twitter.Dispose(); + this.TwitterApi.Dispose(); } } } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index a382b1de8..86a11eae3 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -136,7 +136,6 @@ public partial class TweenMain : OTBaseForm private readonly SettingManager settings; // twitter解析部 - private readonly TwitterApi twitterApi = new(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret); private readonly Twitter tw; // Growl呼び出し部 @@ -480,7 +479,6 @@ protected override void Dispose(bool disposing) this.thumbnailTokenSource?.Dispose(); - this.twitterApi.Dispose(); this.hookGlobalHotkey.Dispose(); } @@ -747,10 +745,11 @@ private void InitColumnText() } } - public TweenMain(SettingManager settingManager, TabInformations tabInfo) + public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter twitter) { this.settings = settingManager; this.statuses = tabInfo; + this.tw = twitter; this.InitializeComponent(); @@ -810,7 +809,6 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo) } TwitterApiConnection.RestApiHost = this.settings.Common.TwitterApiHost; - this.tw = new Twitter(this.twitterApi); // 認証関連 this.tw.Initialize(this.settings.Common.Token, this.settings.Common.TokenSecret, this.settings.Common.UserName, this.settings.Common.UserId); @@ -879,7 +877,7 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo) imgazyobizinet.Enabled = this.settings.Common.EnableImgAzyobuziNet; imgazyobizinet.DisabledInDM = this.settings.Common.ImgAzyobuziNetDisabledInDM; - Thumbnail.Services.TonTwitterCom.GetApiConnection = () => this.twitterApi.Connection; + Thumbnail.Services.TonTwitterCom.GetApiConnection = () => this.tw.Api.Connection; // 画像投稿サービス this.ImageSelector.Initialize(this.tw, this.tw.Configuration, this.settings.Common.UseImageServiceName, this.settings.Common.UseImageService); @@ -2243,7 +2241,7 @@ await Task.Run(async () => { try { - await this.twitterApi.FavoritesCreate(post.RetweetedId ?? post.StatusId) + await this.tw.Api.FavoritesCreate(post.RetweetedId ?? post.StatusId) .IgnoreResponse() .ConfigureAwait(false); } @@ -2255,7 +2253,7 @@ await this.twitterApi.FavoritesCreate(post.RetweetedId ?? post.StatusId) if (this.settings.Common.RestrictFavCheck) { - var status = await this.twitterApi.StatusesShow(post.RetweetedId ?? post.StatusId) + var status = await this.tw.Api.StatusesShow(post.RetweetedId ?? post.StatusId) .ConfigureAwait(false); if (status.Favorited != true) @@ -2369,7 +2367,7 @@ await Task.Run(async () => try { - await this.twitterApi.FavoritesDestroy(post.RetweetedId ?? post.StatusId) + await this.tw.Api.FavoritesDestroy(post.RetweetedId ?? post.StatusId) .IgnoreResponse() .ConfigureAwait(false); } @@ -3113,7 +3111,7 @@ private void ContextMenuOperate_Opening(object sender, CancelEventArgs e) this.StatusOpenMenuItem.Enabled = true; this.ShowRelatedStatusesMenuItem.Enabled = true; // PublicSearchの時問題出るかも - if (!post.CanRetweetBy(this.twitterApi.CurrentUserId)) + if (!post.CanRetweetBy(this.tw.UserId)) { this.ReTweetStripMenuItem.Enabled = false; this.ReTweetUnofficialStripMenuItem.Enabled = false; @@ -3191,7 +3189,7 @@ private async Task DoStatusDelete() { if (post.IsDm) { - await this.twitterApi.DirectMessagesEventsDestroy(post.StatusId.ToString(CultureInfo.InvariantCulture)); + await this.tw.Api.DirectMessagesEventsDestroy(post.StatusId.ToString(CultureInfo.InvariantCulture)); } else { @@ -3199,7 +3197,7 @@ private async Task DoStatusDelete() { // 自分が RT したツイート (自分が RT した自分のツイートも含む) // => RT を取り消し - await this.twitterApi.StatusesDestroy(post.StatusId) + await this.tw.Api.StatusesDestroy(post.StatusId) .IgnoreResponse(); } else @@ -3210,14 +3208,14 @@ await this.twitterApi.StatusesDestroy(post.StatusId) { // 他人に RT された自分のツイート // => RT 元の自分のツイートを削除 - await this.twitterApi.StatusesDestroy(post.RetweetedId.Value) + await this.tw.Api.StatusesDestroy(post.RetweetedId.Value) .IgnoreResponse(); } else { // 自分のツイート // => ツイートを削除 - await this.twitterApi.StatusesDestroy(post.StatusId) + await this.tw.Api.StatusesDestroy(post.StatusId) .IgnoreResponse(); } } @@ -3359,7 +3357,6 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) settingDialog.IntervalChanged += this.TimerInterval_Changed; settingDialog.Tw = this.tw; - settingDialog.TwitterApi = this.twitterApi; settingDialog.LoadConfig(this.settings.Common, this.settings.Local); @@ -9395,7 +9392,7 @@ private async Task DoReTweetOfficial(bool isConfirm) { var selectedPosts = this.CurrentTab.SelectedPosts; - if (selectedPosts.Any(x => !x.CanRetweetBy(this.twitterApi.CurrentUserId))) + if (selectedPosts.Any(x => !x.CanRetweetBy(this.tw.UserId))) { if (selectedPosts.Any(x => x.IsProtect)) MessageBox.Show("Protected."); @@ -9652,7 +9649,7 @@ internal async Task FollowCommand(string id) { try { - var task = this.twitterApi.FriendshipsCreate(id).IgnoreResponse(); + var task = this.tw.Api.FriendshipsCreate(id).IgnoreResponse(); await dialog.WaitForAsync(this, task); } catch (WebApiException ex) @@ -9693,7 +9690,7 @@ internal async Task RemoveCommand(string id, bool skipInput) { try { - var task = this.twitterApi.FriendshipsDestroy(id).IgnoreResponse(); + var task = this.tw.Api.FriendshipsDestroy(id).IgnoreResponse(); await dialog.WaitForAsync(this, task); } catch (WebApiException ex) @@ -9737,7 +9734,7 @@ internal async Task ShowFriendship(string id) try { - var task = this.twitterApi.FriendshipsShow(this.twitterApi.CurrentScreenName, id); + var task = this.tw.Api.FriendshipsShow(this.tw.Username, id); var friendship = await dialog.WaitForAsync(this, task); isFollowing = friendship.Relationship.Source.Following; @@ -9787,7 +9784,7 @@ internal async Task ShowFriendship(string[] ids) try { - var task = this.twitterApi.FriendshipsShow(this.twitterApi.CurrentScreenName, id); + var task = this.tw.Api.FriendshipsShow(this.tw.Username, id); var friendship = await dialog.WaitForAsync(this, task); isFollowing = friendship.Relationship.Source.Following; @@ -10106,7 +10103,7 @@ private void RetweetedByListManageMenuItem_Click(object sender, EventArgs e) public void ListManageUserContext(string screenName) { - using var listSelectForm = new MyLists(screenName, this.twitterApi); + using var listSelectForm = new MyLists(screenName, this.tw.Api); listSelectForm.ShowDialog(this); } @@ -10252,7 +10249,7 @@ private void MenuItemOperate_DropDownOpening(object sender, EventArgs e) this.OpenStatusOpMenuItem.Enabled = true; this.ShowRelatedStatusesMenuItem2.Enabled = true; // PublicSearchの時問題出るかも - if (!post.CanRetweetBy(this.twitterApi.CurrentUserId)) + if (!post.CanRetweetBy(this.tw.UserId)) { this.RtOpMenuItem.Enabled = false; this.RtUnOpMenuItem.Enabled = false; @@ -10389,7 +10386,7 @@ private async Task DoShowUserStatus(string id, bool showInputDialog) try { - var task = this.twitterApi.UsersShow(id); + var task = this.tw.Api.UsersShow(id); user = await dialog.WaitForAsync(this, task); } catch (WebApiException ex) @@ -10408,7 +10405,7 @@ private async Task DoShowUserStatus(string id, bool showInputDialog) private async Task DoShowUserStatus(TwitterUser user) { - using var userDialog = new UserInfoDialog(this, this.twitterApi); + using var userDialog = new UserInfoDialog(this, this.tw.Api); var showUserTask = userDialog.ShowUserAsync(user); userDialog.ShowDialog(this); @@ -10458,7 +10455,7 @@ private async void RtCountMenuItem_Click(object sender, EventArgs e) try { - var task = this.twitterApi.StatusesShow(statusId); + var task = this.tw.Api.StatusesShow(statusId); status = await dialog.WaitForAsync(this, task); } catch (WebApiException ex) From b1a6b628f0dc5991453d1b79f04e5642c63f1dda Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 09:51:04 +0900 Subject: [PATCH 161/402] =?UTF-8?q?=E9=9D=99=E7=9A=84=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E3=83=89=E3=81=AB=E5=AF=BE=E3=81=99=E3=82=8B?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E5=80=A4=E3=81=AE=E9=81=A9=E7=94=A8=E3=82=92?= =?UTF-8?q?SettingManager=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 4 ++++ OpenTween/Setting/SettingManager.cs | 23 ++++++++++++++++++ OpenTween/Tween.cs | 36 +---------------------------- 3 files changed, 28 insertions(+), 35 deletions(-) diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index c5837e678..2c7f13419 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -30,6 +30,7 @@ using System; using System.IO; using System.Windows.Forms; +using OpenTween.Connection; using OpenTween.Setting; namespace OpenTween @@ -71,6 +72,9 @@ public static int Main(string[] args) container.CultureService.Initialize(); + Networking.Initialize(); + settings.ApplySettings(); + // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する using var mutex = new ApplicationInstanceMutex(ApplicationSettings.AssemblyName, MyCommon.SettingPath); diff --git a/OpenTween/Setting/SettingManager.cs b/OpenTween/Setting/SettingManager.cs index 0ae80f7c9..30c97dd0a 100644 --- a/OpenTween/Setting/SettingManager.cs +++ b/OpenTween/Setting/SettingManager.cs @@ -26,6 +26,8 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using OpenTween.Connection; +using OpenTween.Thumbnail; namespace OpenTween.Setting { @@ -101,5 +103,26 @@ public void SaveTabs() public void SaveAtIdList() => this.AtIdList.Save(); + + public void ApplySettings() + { + // 静的フィールドにセットする必要のある設定値を更新 + Networking.DefaultTimeout = TimeSpan.FromSeconds(this.Common.DefaultTimeOut); + Networking.UploadImageTimeout = TimeSpan.FromSeconds(this.Common.UploadImageTimeout); + Networking.ForceIPv4 = this.Common.ForceIPv4; + Networking.SetWebProxy( + this.Local.ProxyType, + this.Local.ProxyAddress, + this.Local.ProxyPort, + this.Local.ProxyUser, + this.Local.ProxyPassword); + + TwitterApiConnection.RestApiHost = this.Common.TwitterApiHost; + + ShortUrl.Instance.DisableExpanding = !this.Common.TinyUrlResolve; + ShortUrl.Instance.BitlyAccessToken = this.Common.BitlyAccessToken; + ShortUrl.Instance.BitlyId = this.Common.BilyUser; + ShortUrl.Instance.BitlyKey = this.Common.BitlyPwd; + } } } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 86a11eae3..71567d419 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -808,15 +808,11 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter this.Font = fontUIGlobal; } - TwitterApiConnection.RestApiHost = this.settings.Common.TwitterApiHost; - // 認証関連 this.tw.Initialize(this.settings.Common.Token, this.settings.Common.TokenSecret, this.settings.Common.UserName, this.settings.Common.UserId); this.initial = true; - Networking.Initialize(); - var saveRequired = false; var firstRun = false; @@ -834,24 +830,8 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter } } - // Twitter用通信クラス初期化 - Networking.DefaultTimeout = TimeSpan.FromSeconds(this.settings.Common.DefaultTimeOut); - Networking.UploadImageTimeout = TimeSpan.FromSeconds(this.settings.Common.UploadImageTimeout); - Networking.SetWebProxy( - this.settings.Local.ProxyType, - this.settings.Local.ProxyAddress, - this.settings.Local.ProxyPort, - this.settings.Local.ProxyUser, - this.settings.Local.ProxyPassword); - Networking.ForceIPv4 = this.settings.Common.ForceIPv4; - - TwitterApiConnection.RestApiHost = this.settings.Common.TwitterApiHost; this.tw.RestrictFavCheck = this.settings.Common.RestrictFavCheck; this.tw.ReadOwnPost = this.settings.Common.ReadOwnPost; - ShortUrl.Instance.DisableExpanding = !this.settings.Common.TinyUrlResolve; - ShortUrl.Instance.BitlyAccessToken = this.settings.Common.BitlyAccessToken; - ShortUrl.Instance.BitlyId = this.settings.Common.BilyUser; - ShortUrl.Instance.BitlyKey = this.settings.Common.BitlyPwd; // アクセストークンが有効であるか確認する // ここが Twitter API への最初のアクセスになるようにすること @@ -3391,23 +3371,9 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) { lock (this.syncObject) { + this.settings.ApplySettings(); this.tw.RestrictFavCheck = this.settings.Common.RestrictFavCheck; this.tw.ReadOwnPost = this.settings.Common.ReadOwnPost; - ShortUrl.Instance.DisableExpanding = !this.settings.Common.TinyUrlResolve; - ShortUrl.Instance.BitlyAccessToken = this.settings.Common.BitlyAccessToken; - ShortUrl.Instance.BitlyId = this.settings.Common.BilyUser; - ShortUrl.Instance.BitlyKey = this.settings.Common.BitlyPwd; - TwitterApiConnection.RestApiHost = this.settings.Common.TwitterApiHost; - - Networking.DefaultTimeout = TimeSpan.FromSeconds(this.settings.Common.DefaultTimeOut); - Networking.UploadImageTimeout = TimeSpan.FromSeconds(this.settings.Common.UploadImageTimeout); - Networking.SetWebProxy( - this.settings.Local.ProxyType, - this.settings.Local.ProxyAddress, - this.settings.Local.ProxyPort, - this.settings.Local.ProxyUser, - this.settings.Local.ProxyPassword); - Networking.ForceIPv4 = this.settings.Common.ForceIPv4; this.ImageSelector.Reset(this.tw, this.tw.Configuration); From e023d1e65993f7f3eff87eaa50e70b2031755668 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 10:09:56 +0900 Subject: [PATCH 162/402] =?UTF-8?q?ImageCache=E3=81=AE=E5=88=9D=E6=9C=9F?= =?UTF-8?q?=E5=8C=96=E3=82=92ApplicationContainer=E3=81=AB=E7=A7=BB?= =?UTF-8?q?=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationContainer.cs | 12 +++++++++++- OpenTween/Tween.cs | 11 ++--------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/OpenTween/ApplicationContainer.cs b/OpenTween/ApplicationContainer.cs index 7de7d0067..1dfdc0fa9 100644 --- a/OpenTween/ApplicationContainer.cs +++ b/OpenTween/ApplicationContainer.cs @@ -45,12 +45,16 @@ public TwitterApi TwitterApi public Twitter Twitter => this.twitterLazy.Value; + public ImageCache ImageCache + => this.imageCacheLazy.Value; + public TweenMain MainForm => this.mainFormLazy.Value; private readonly Lazy cultureServiceLazy; private readonly Lazy twitterApiLazy; private readonly Lazy twitterLazy; + private readonly Lazy imageCacheLazy; private readonly Lazy mainFormLazy; public ApplicationContainer() @@ -58,6 +62,7 @@ public ApplicationContainer() this.cultureServiceLazy = new(this.CreateCultureService); this.twitterApiLazy = new(this.CreateTwitterApi); this.twitterLazy = new(this.CreateTwitter); + this.imageCacheLazy = new(this.CreateImageCache); this.mainFormLazy = new(this.CreateTweenMain); } @@ -70,8 +75,11 @@ private TwitterApi CreateTwitterApi() private Twitter CreateTwitter() => new(this.TwitterApi); + private ImageCache CreateImageCache() + => new(); + private TweenMain CreateTweenMain() - => new(this.Settings, this.TabInfo, this.Twitter); + => new(this.Settings, this.TabInfo, this.Twitter, this.ImageCache); public void Dispose() { @@ -82,6 +90,8 @@ public void Dispose() this.MainForm.Dispose(); this.Twitter.Dispose(); this.TwitterApi.Dispose(); + this.ImageCache.CancelAsync(); + this.ImageCache.Dispose(); } } } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 71567d419..48fbda247 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -470,13 +470,6 @@ protected override void Dispose(bool disposing) this.timelineScheduler.Dispose(); this.workerCts.Cancel(); - - if (this.iconCache != null) - { - this.iconCache.CancelAsync(); - this.iconCache.Dispose(); - } - this.thumbnailTokenSource?.Dispose(); this.hookGlobalHotkey.Dispose(); @@ -745,11 +738,12 @@ private void InitColumnText() } } - public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter twitter) + public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter twitter, ImageCache imageCache) { this.settings = settingManager; this.statuses = tabInfo; this.tw = twitter; + this.iconCache = imageCache; this.InitializeComponent(); @@ -874,7 +868,6 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter if (!MyCommon.IsNullOrEmpty(this.HashMgr.UseHash) && this.HashMgr.IsPermanent) this.HashStripSplitButton.Text = this.HashMgr.UseHash; // アイコンリスト作成 - this.iconCache = new ImageCache(); this.tweetDetailsView.IconCache = this.iconCache; // フォント&文字色&背景色保持 From f6c96aa967b3717aee5349349ef05d210123ef09 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 10:37:23 +0900 Subject: [PATCH 163/402] =?UTF-8?q?DisposableLazy=20=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/DisposableLazyTest.cs | 85 +++++++++++++++++++++++++++ OpenTween/ApplicationContainer.cs | 17 +++--- OpenTween/DisposableLazy.cs | 55 +++++++++++++++++ OpenTween/OpenTween.csproj | 1 + 4 files changed, 149 insertions(+), 9 deletions(-) create mode 100644 OpenTween.Tests/DisposableLazyTest.cs create mode 100644 OpenTween/DisposableLazy.cs diff --git a/OpenTween.Tests/DisposableLazyTest.cs b/OpenTween.Tests/DisposableLazyTest.cs new file mode 100644 index 000000000..15296f178 --- /dev/null +++ b/OpenTween.Tests/DisposableLazyTest.cs @@ -0,0 +1,85 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Moq; +using Xunit; + +namespace OpenTween +{ + public class DisposableLazyTest + { + [Fact] + public void Value_Test() + { + var mock = new Mock(); + var obj = mock.Object; + + var lazy = new DisposableLazy(() => obj); + Assert.False(lazy.IsValueCreated); + Assert.Equal(obj, lazy.Value); + Assert.True(lazy.IsValueCreated); + } + + [Fact] + public void Value_DisposedErrorTest() + { + var mock = new Mock(); + var obj = mock.Object; + + var lazy = new DisposableLazy(() => obj); + lazy.Dispose(); + + Assert.Throws(() => lazy.Value); + } + + [Fact] + public void Dispose_BeforeValueCreatedTest() + { + var mock = new Mock(); + + var lazy = new DisposableLazy(() => mock.Object); + lazy.Dispose(); + + Assert.False(lazy.IsValueCreated); + Assert.True(lazy.IsDisposed); + mock.Verify(x => x.Dispose(), Times.Never()); + } + + [Fact] + public void Dispose_AfterValueCreatedTest() + { + var mock = new Mock(); + + var lazy = new DisposableLazy(() => mock.Object); + _ = lazy.Value; + lazy.Dispose(); + + Assert.True(lazy.IsValueCreated); + Assert.True(lazy.IsDisposed); + mock.Verify(x => x.Dispose(), Times.Once()); + } + } +} diff --git a/OpenTween/ApplicationContainer.cs b/OpenTween/ApplicationContainer.cs index 1dfdc0fa9..36eb82042 100644 --- a/OpenTween/ApplicationContainer.cs +++ b/OpenTween/ApplicationContainer.cs @@ -52,10 +52,10 @@ public TweenMain MainForm => this.mainFormLazy.Value; private readonly Lazy cultureServiceLazy; - private readonly Lazy twitterApiLazy; - private readonly Lazy twitterLazy; - private readonly Lazy imageCacheLazy; - private readonly Lazy mainFormLazy; + private readonly DisposableLazy twitterApiLazy; + private readonly DisposableLazy twitterLazy; + private readonly DisposableLazy imageCacheLazy; + private readonly DisposableLazy mainFormLazy; public ApplicationContainer() { @@ -87,11 +87,10 @@ public void Dispose() return; this.IsDisposed = true; - this.MainForm.Dispose(); - this.Twitter.Dispose(); - this.TwitterApi.Dispose(); - this.ImageCache.CancelAsync(); - this.ImageCache.Dispose(); + this.mainFormLazy.Dispose(); + this.twitterLazy.Dispose(); + this.twitterApiLazy.Dispose(); + this.imageCacheLazy.Dispose(); } } } diff --git a/OpenTween/DisposableLazy.cs b/OpenTween/DisposableLazy.cs new file mode 100644 index 000000000..9687c12bf --- /dev/null +++ b/OpenTween/DisposableLazy.cs @@ -0,0 +1,55 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; + +namespace OpenTween +{ + public sealed class DisposableLazy : IDisposable + where T : IDisposable + { + public bool IsDisposed { get; private set; } = false; + + public T Value + => !this.IsDisposed ? this.lazy.Value : throw new ObjectDisposedException(nameof(this.lazy)); + + public bool IsValueCreated + => this.lazy.IsValueCreated; + + private readonly Lazy lazy; + + public DisposableLazy(Func factory) + => this.lazy = new(factory); + + public void Dispose() + { + if (this.IsDisposed) + return; + + if (this.IsValueCreated) + this.Value.Dispose(); + + this.IsDisposed = true; + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index d85932a01..7e879925f 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -131,6 +131,7 @@ + From 1b10e7955a7e5ba4b0e1243bc2be4936eb762684 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 4 Apr 2022 14:28:00 +0900 Subject: [PATCH 164/402] =?UTF-8?q?=E3=82=A2=E3=82=A4=E3=82=B3=E3=83=B3?= =?UTF-8?q?=E3=81=AE=E5=88=9D=E6=9C=9F=E5=8C=96=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?IconAssetsManager=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=AB=E5=88=86?= =?UTF-8?q?=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationContainer.cs | 11 +- OpenTween/IconAssetsManager.cs | 173 ++++++++++++++++++++++++++++++ OpenTween/OpenTween.csproj | 1 + OpenTween/Tween.cs | 148 +++---------------------- 4 files changed, 198 insertions(+), 135 deletions(-) create mode 100644 OpenTween/IconAssetsManager.cs diff --git a/OpenTween/ApplicationContainer.cs b/OpenTween/ApplicationContainer.cs index 36eb82042..5d63d7371 100644 --- a/OpenTween/ApplicationContainer.cs +++ b/OpenTween/ApplicationContainer.cs @@ -48,6 +48,9 @@ public Twitter Twitter public ImageCache ImageCache => this.imageCacheLazy.Value; + public IconAssetsManager IconAssetsManager + => this.iconAssetsManagerLazy.Value; + public TweenMain MainForm => this.mainFormLazy.Value; @@ -55,6 +58,7 @@ public TweenMain MainForm private readonly DisposableLazy twitterApiLazy; private readonly DisposableLazy twitterLazy; private readonly DisposableLazy imageCacheLazy; + private readonly DisposableLazy iconAssetsManagerLazy; private readonly DisposableLazy mainFormLazy; public ApplicationContainer() @@ -63,6 +67,7 @@ public ApplicationContainer() this.twitterApiLazy = new(this.CreateTwitterApi); this.twitterLazy = new(this.CreateTwitter); this.imageCacheLazy = new(this.CreateImageCache); + this.iconAssetsManagerLazy = new(this.CreateIconAssetsManager); this.mainFormLazy = new(this.CreateTweenMain); } @@ -78,8 +83,11 @@ private Twitter CreateTwitter() private ImageCache CreateImageCache() => new(); + private IconAssetsManager CreateIconAssetsManager() + => new(); + private TweenMain CreateTweenMain() - => new(this.Settings, this.TabInfo, this.Twitter, this.ImageCache); + => new(this.Settings, this.TabInfo, this.Twitter, this.ImageCache, this.IconAssetsManager); public void Dispose() { @@ -90,6 +98,7 @@ public void Dispose() this.mainFormLazy.Dispose(); this.twitterLazy.Dispose(); this.twitterApiLazy.Dispose(); + this.iconAssetsManagerLazy.Dispose(); this.imageCacheLazy.Dispose(); } } diff --git a/OpenTween/IconAssetsManager.cs b/OpenTween/IconAssetsManager.cs new file mode 100644 index 000000000..b416efe2b --- /dev/null +++ b/OpenTween/IconAssetsManager.cs @@ -0,0 +1,173 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) +// (c) 2008-2011 Moz (@syo68k) +// (c) 2008-2011 takeshik (@takeshik) +// (c) 2010-2011 anis774 (@anis774) +// (c) 2010-2011 fantasticswallow (@f_swallow) +// (c) 2011 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Drawing; +using System.IO; +using System.Windows.Forms; + +namespace OpenTween +{ + public sealed class IconAssetsManager : IDisposable + { + public bool IsDisposed { get; private set; } = false; + + /// ウィンドウ左上のアイコン + public Icon IconMain { get; } + + /// タブ見出し未読表示アイコン + public Icon IconTab { get; } + + /// タスクトレイ: 通常時アイコン + public Icon IconTray { get; } + + /// タスクトレイ: エラー時アイコン + public Icon IconTrayError { get; } + + /// タスクトレイ: オフライン時アイコン + public Icon IconTrayOffline { get; } + + /// タスクトレイ: Reply通知アイコン + public Icon IconTrayReply { get; } + + /// タスクトレイ: Reply通知アイコン(点滅時) + public Icon IconTrayReplyBlink { get; } + + /// タスクトレイ: 更新中アイコン + public Icon[] IconTrayRefresh { get; } + + private readonly Icon? iconMain; + private readonly Icon? iconTab; + private readonly Icon? iconAt; + private readonly Icon? iconAtRed; + private readonly Icon? iconAtSmoke; + private readonly Icon? iconReply; + private readonly Icon? iconReplyBlink; + private readonly Icon? iconRefresh1; + private readonly Icon? iconRefresh2; + private readonly Icon? iconRefresh3; + private readonly Icon? iconRefresh4; + + public IconAssetsManager() + : this(Path.Combine(Application.StartupPath, "Icons")) + { + } + + public IconAssetsManager(string iconsDir) + { + this.iconMain = this.LoadIcon(iconsDir, "MIcon.ico"); + this.iconTab = this.LoadIcon(iconsDir, "Tab.ico"); + this.iconAt = this.LoadIcon(iconsDir, "At.ico"); + this.iconAtRed = this.LoadIcon(iconsDir, "AtRed.ico"); + this.iconAtSmoke = this.LoadIcon(iconsDir, "AtSmoke.ico"); + this.iconReply = this.LoadIcon(iconsDir, "Reply.ico"); + this.iconReplyBlink = this.LoadIcon(iconsDir, "ReplyBlink.ico"); + this.iconRefresh1 = this.LoadIcon(iconsDir, "Refresh.ico"); + this.iconRefresh2 = this.LoadIcon(iconsDir, "Refresh2.ico"); + this.iconRefresh3 = this.LoadIcon(iconsDir, "Refresh3.ico"); + this.iconRefresh4 = this.LoadIcon(iconsDir, "Refresh4.ico"); + + this.IconMain = this.iconMain ?? Properties.Resources.MIcon; + this.IconTab = this.iconTab ?? Properties.Resources.TabIcon; + this.IconTray = this.iconAt ?? this.iconMain ?? Properties.Resources.At; + this.IconTrayError = this.iconAtRed ?? Properties.Resources.AtRed; + this.IconTrayOffline = this.iconAtSmoke ?? Properties.Resources.AtSmoke; + + if (this.iconReply != null && this.iconReplyBlink != null) + { + this.IconTrayReply = this.iconReply; + this.IconTrayReplyBlink = this.iconReplyBlink; + } + else + { + this.IconTrayReply = this.iconReply ?? this.iconReplyBlink ?? Properties.Resources.Reply; + this.IconTrayReplyBlink = this.IconTray; + } + + if (this.iconRefresh1 == null) + { + this.IconTrayRefresh = new[] + { + Properties.Resources.Refresh, Properties.Resources.Refresh2, + Properties.Resources.Refresh3, Properties.Resources.Refresh4, + }; + } + else if (this.iconRefresh2 == null) + { + this.IconTrayRefresh = new[] { this.iconRefresh1 }; + } + else if (this.iconRefresh3 == null) + { + this.IconTrayRefresh = new[] { this.iconRefresh1, this.iconRefresh2 }; + } + else if (this.iconRefresh4 == null) + { + this.IconTrayRefresh = new[] { this.iconRefresh1, this.iconRefresh2, this.iconRefresh3 }; + } + else // iconRefresh1 から iconRefresh4 まで全て揃っている + { + this.IconTrayRefresh = new[] { this.iconRefresh1, this.iconRefresh2, this.iconRefresh3, this.iconRefresh4 }; + } + } + + private Icon? LoadIcon(string baseDir, string fileName) + { + var filePath = Path.Combine(baseDir, fileName); + if (!File.Exists(filePath)) + return null; + + try + { + return new(filePath); + } + catch + { + return null; + } + } + + public void Dispose() + { + if (this.IsDisposed) + return; + + this.iconMain?.Dispose(); + this.iconTab?.Dispose(); + this.iconAt?.Dispose(); + this.iconAtRed?.Dispose(); + this.iconAtSmoke?.Dispose(); + this.iconReply?.Dispose(); + this.iconReplyBlink?.Dispose(); + this.iconRefresh1?.Dispose(); + this.iconRefresh2?.Dispose(); + this.iconRefresh3?.Dispose(); + this.iconRefresh4?.Dispose(); + this.IsDisposed = true; + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 7e879925f..f577c7c16 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -107,6 +107,7 @@ + Form diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 48fbda247..f69803900 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -227,26 +227,7 @@ public partial class TweenMain : OTBaseForm /// アイコン画像リスト private readonly ImageCache iconCache; - /// タスクトレイアイコン:通常時 (At.ico) - private Icon nIconAt = null!; - - /// タスクトレイアイコン:通信エラー時 (AtRed.ico) - private Icon nIconAtRed = null!; - - /// タスクトレイアイコン:オフライン時 (AtSmoke.ico) - private Icon nIconAtSmoke = null!; - - /// タスクトレイアイコン:更新中 (Refresh.ico) - private Icon[] nIconRefresh = new Icon[4]; - - /// 未読のあるタブ用アイコン (Tab.ico) - private Icon tabIcon = null!; - - /// 画面左上のアイコン (Main.ico) - private Icon mainIcon = null!; - - private Icon replyIcon = null!; - private Icon replyIconBlink = null!; + private readonly IconAssetsManager iconAssets; private readonly ImageList listViewImageList = new(); // ListViewItemの高さ変更用 @@ -445,17 +426,6 @@ protected override void Dispose(bool disposing) // 後始末 this.SearchDialog.Dispose(); this.urlDialog.Dispose(); - this.nIconAt?.Dispose(); - this.nIconAtRed?.Dispose(); - this.nIconAtSmoke?.Dispose(); - foreach (var iconRefresh in this.nIconRefresh) - { - iconRefresh?.Dispose(); - } - this.tabIcon?.Dispose(); - this.mainIcon?.Dispose(); - this.replyIcon?.Dispose(); - this.replyIconBlink?.Dispose(); this.listViewImageList.Dispose(); this.brsHighLight.Dispose(); this.brsBackColorMine?.Dispose(); @@ -483,96 +453,6 @@ protected override void Dispose(bool disposing) this.disposed = true; } - private void LoadIcons() - { - // Icons フォルダ以下のアイコンを読み込み(着せ替えアイコン対応) - var iconsDir = Path.Combine(Application.StartupPath, "Icons"); - - // ウィンドウ左上のアイコン - var iconMain = this.LoadIcon(Path.Combine(iconsDir, "MIcon.ico")); - - // タブ見出し未読表示アイコン - var iconTab = this.LoadIcon(Path.Combine(iconsDir, "Tab.ico")); - - // タスクトレイ: 通常時アイコン - var iconAt = this.LoadIcon(Path.Combine(iconsDir, "At.ico")); - - // タスクトレイ: エラー時アイコン - var iconAtRed = this.LoadIcon(Path.Combine(iconsDir, "AtRed.ico")); - - // タスクトレイ: オフライン時アイコン - var iconAtSmoke = this.LoadIcon(Path.Combine(iconsDir, "AtSmoke.ico")); - - // タスクトレイ: Reply通知アイコン (最大2枚でアニメーション可能) - var iconReply = this.LoadIcon(Path.Combine(iconsDir, "Reply.ico")); - var iconReplyBlink = this.LoadIcon(Path.Combine(iconsDir, "ReplyBlink.ico")); - - // タスクトレイ: 更新中アイコン (最大4枚でアニメーション可能) - var iconRefresh1 = this.LoadIcon(Path.Combine(iconsDir, "Refresh.ico")); - var iconRefresh2 = this.LoadIcon(Path.Combine(iconsDir, "Refresh2.ico")); - var iconRefresh3 = this.LoadIcon(Path.Combine(iconsDir, "Refresh3.ico")); - var iconRefresh4 = this.LoadIcon(Path.Combine(iconsDir, "Refresh4.ico")); - - // 読み込んだアイコンを設定 (不足するアイコンはデフォルトのものを設定) - - this.mainIcon = iconMain ?? Properties.Resources.MIcon; - this.tabIcon = iconTab ?? Properties.Resources.TabIcon; - this.nIconAt = iconAt ?? iconMain ?? Properties.Resources.At; - this.nIconAtRed = iconAtRed ?? Properties.Resources.AtRed; - this.nIconAtSmoke = iconAtSmoke ?? Properties.Resources.AtSmoke; - - if (iconReply != null && iconReplyBlink != null) - { - this.replyIcon = iconReply; - this.replyIconBlink = iconReplyBlink; - } - else - { - this.replyIcon = iconReply ?? iconReplyBlink ?? Properties.Resources.Reply; - this.replyIconBlink = this.nIconAt; - } - - if (iconRefresh1 == null) - { - this.nIconRefresh = new[] - { - Properties.Resources.Refresh, Properties.Resources.Refresh2, - Properties.Resources.Refresh3, Properties.Resources.Refresh4, - }; - } - else if (iconRefresh2 == null) - { - this.nIconRefresh = new[] { iconRefresh1 }; - } - else if (iconRefresh3 == null) - { - this.nIconRefresh = new[] { iconRefresh1, iconRefresh2 }; - } - else if (iconRefresh4 == null) - { - this.nIconRefresh = new[] { iconRefresh1, iconRefresh2, iconRefresh3 }; - } - else // iconRefresh1 から iconRefresh4 まで全て揃っている - { - this.nIconRefresh = new[] { iconRefresh1, iconRefresh2, iconRefresh3, iconRefresh4 }; - } - } - - private Icon? LoadIcon(string filePath) - { - if (!File.Exists(filePath)) - return null; - - try - { - return new Icon(filePath); - } - catch (Exception) - { - return null; - } - } - private void InitColumns(ListView list, bool startup) { this.InitColumnText(); @@ -738,12 +618,13 @@ private void InitColumnText() } } - public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter twitter, ImageCache imageCache) + public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter twitter, ImageCache imageCache, IconAssetsManager iconAssets) { this.settings = settingManager; this.statuses = tabInfo; this.tw = twitter; this.iconCache = imageCache; + this.iconAssets = iconAssets; this.InitializeComponent(); @@ -782,10 +663,9 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter Regex.CacheSize = 100; // アイコン設定 - this.LoadIcons(); - this.Icon = this.mainIcon; // メインフォーム(TweenMain) - this.NotifyIcon1.Icon = this.nIconAt; // タスクトレイ - this.TabImage.Images.Add(this.tabIcon); // タブ見出し + this.Icon = this.iconAssets.IconMain; // メインフォーム(TweenMain) + this.NotifyIcon1.Icon = this.iconAssets.IconTray; // タスクトレイ + this.TabImage.Images.Add(this.iconAssets.IconTab); // タブ見出し // <<<<<<<<<設定関連>>>>>>>>> // 設定読み出し @@ -3324,7 +3204,7 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) var result = DialogResult.Abort; using var settingDialog = new AppendSettingDialog(); - settingDialog.Icon = this.mainIcon; + settingDialog.Icon = this.iconAssets.IconMain; settingDialog.Owner = this; settingDialog.ShowInTaskbar = showTaskbarIcon; settingDialog.IntervalChanged += this.TimerInterval_Changed; @@ -7370,10 +7250,10 @@ void DisableTasktrayAnimation() if (busyTasks) { this.iconCnt += 1; - if (this.iconCnt >= this.nIconRefresh.Length) + if (this.iconCnt >= this.iconAssets.IconTrayRefresh.Length) this.iconCnt = 0; - this.NotifyIcon1.Icon = this.nIconRefresh[this.iconCnt]; + this.NotifyIcon1.Icon = this.iconAssets.IconTrayRefresh[this.iconCnt]; this.myStatusError = false; EnableTasktrayAnimation(); return; @@ -7397,7 +7277,7 @@ void DisableTasktrayAnimation() if (this.blinkCnt == 0) this.blink = !this.blink; - this.NotifyIcon1.Icon = this.blink ? this.replyIconBlink : this.replyIcon; + this.NotifyIcon1.Icon = this.blink ? this.iconAssets.IconTrayReplyBlink : this.iconAssets.IconTrayReply; EnableTasktrayAnimation(); return; } @@ -7411,13 +7291,13 @@ void DisableTasktrayAnimation() // 優先度:リプライ→エラー→オフライン→アイドル // エラーは更新アイコンでクリアされる if (replyIconType == MyCommon.REPLY_ICONSTATE.StaticIcon && reply) - this.NotifyIcon1.Icon = this.replyIcon; + this.NotifyIcon1.Icon = this.iconAssets.IconTrayReply; else if (this.myStatusError) - this.NotifyIcon1.Icon = this.nIconAtRed; + this.NotifyIcon1.Icon = this.iconAssets.IconTrayError; else if (this.myStatusOnline) - this.NotifyIcon1.Icon = this.nIconAt; + this.NotifyIcon1.Icon = this.iconAssets.IconTray; else - this.NotifyIcon1.Icon = this.nIconAtSmoke; + this.NotifyIcon1.Icon = this.iconAssets.IconTrayOffline; } private void TimerRefreshIcon_Tick(object sender, EventArgs e) From 6555e55f3fd2964d3a04fd3371b536bd1a806143 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 8 Apr 2022 08:18:50 +0900 Subject: [PATCH 165/402] =?UTF-8?q?Font,=20Color,=20Brush=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=82=B9=E3=82=BF=E3=83=B3=E3=82=B9=E3=81=AE=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E3=82=92ThemeManager=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 1 + OpenTween/OpenTween.csproj | 1 + OpenTween/ThemeManager.cs | 180 ++++++++++++++++++++ OpenTween/Tween.cs | 292 +++++++-------------------------- OpenTween/TweetDetailsView.cs | 40 ++++- 5 files changed, 275 insertions(+), 239 deletions(-) create mode 100644 OpenTween/ThemeManager.cs diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 2c7f13419..a25638c53 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -70,6 +70,7 @@ public static int Main(string[] args) var noLimit = StartupOptions.ContainsKey("nolimit"); settings.Common.Validate(noLimit); + ThemeManager.ApplyGlobalUIFont(settings.Local); container.CultureService.Initialize(); Networking.Initialize(); diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index f577c7c16..da0ee3d47 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -107,6 +107,7 @@ + diff --git a/OpenTween/ThemeManager.cs b/OpenTween/ThemeManager.cs new file mode 100644 index 000000000..5bccfd487 --- /dev/null +++ b/OpenTween/ThemeManager.cs @@ -0,0 +1,180 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) +// (c) 2008-2011 Moz (@syo68k) +// (c) 2008-2011 takeshik (@takeshik) +// (c) 2010-2011 anis774 (@anis774) +// (c) 2010-2011 fantasticswallow (@f_swallow) +// (c) 2011 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Drawing; + +namespace OpenTween +{ + public sealed class ThemeManager : IDisposable + { + public bool IsDisposed { get; private set; } = false; + + /// 未読用フォント + public Font FontUnread { get; } + + /// 既読用フォント + public Font FontReaded { get; } + + /// 発言詳細部用フォント + public Font FontDetail { get; } + + /// 入力欄フォント + public Font FontInputFont { get; } + + /// 未読用文字色 + public Color ColorUnread { get; } + + /// 既読用文字色 + public Color ColorRead { get; } + + /// Fav用文字色 + public Color ColorFav { get; } + + /// 片思い用文字色 + public Color ColorOWL { get; } + + /// Retweet用文字色 + public Color ColorRetweet { get; } + + /// 選択中の行用文字色 + public Color ColorHighLight { get; } + + /// 発言詳細部用色 + public Color ColorDetail { get; } + + /// 発言詳細部用リンク文字色 + public Color ColorDetailLink { get; } + + /// 発言詳細部用背景色 + public Color ColorDetailBackcolor { get; } + + /// 自分の発言用背景色 + public Color ColorSelf { get; } + + /// 自分宛返信用背景色 + public Color ColorAtSelf { get; } + + /// 選択発言者の他の発言用背景色 + public Color ColorTarget { get; } + + /// 選択発言中の返信先用背景色 + public Color ColorAtTarget { get; } + + /// 選択発言者への返信発言用背景色 + public Color ColorAtFromTarget { get; } + + /// 選択発言の唯一@先 + public Color ColorAtTo { get; } + + /// リスト部通常発言背景色 + public Color ColorListBackcolor { get; } + + /// 入力欄背景色 + public Color ColorInputBackcolor { get; } + + /// 入力欄文字色 + public Color ColorInputFont { get; } + + public Brush BrushSelf { get; } + + public Brush BrushAtSelf { get; } + + public Brush BrushTarget { get; } + + public Brush BrushAtTarget { get; } + + public Brush BrushAtFromTarget { get; } + + public Brush BrushAtTo { get; } + + public Brush BrushListBackcolor { get; } + + public ThemeManager(SettingLocal settingLocal) + { + this.FontUnread = settingLocal.FontUnread; + this.FontReaded = settingLocal.FontRead; + this.FontDetail = settingLocal.FontDetail; + this.FontInputFont = settingLocal.FontInputFont; + + this.ColorUnread = settingLocal.ColorUnread; + this.ColorRead = settingLocal.ColorRead; + this.ColorFav = settingLocal.ColorFav; + this.ColorOWL = settingLocal.ColorOWL; + this.ColorRetweet = settingLocal.ColorRetweet; + this.ColorHighLight = Color.FromKnownColor(KnownColor.HighlightText); + this.ColorDetail = settingLocal.ColorDetail; + this.ColorDetailLink = settingLocal.ColorDetailLink; + this.ColorDetailBackcolor = settingLocal.ColorDetailBackcolor; + this.ColorSelf = settingLocal.ColorSelf; + this.ColorAtSelf = settingLocal.ColorAtSelf; + this.ColorTarget = settingLocal.ColorTarget; + this.ColorAtTarget = settingLocal.ColorAtTarget; + this.ColorAtFromTarget = settingLocal.ColorAtFromTarget; + this.ColorAtTo = settingLocal.ColorAtTo; + this.ColorListBackcolor = settingLocal.ColorListBackcolor; + this.ColorInputBackcolor = settingLocal.ColorInputBackcolor; + this.ColorInputFont = settingLocal.ColorInputFont; + + this.BrushSelf = new SolidBrush(this.ColorSelf); + this.BrushAtSelf = new SolidBrush(this.ColorAtSelf); + this.BrushTarget = new SolidBrush(this.ColorTarget); + this.BrushAtTarget = new SolidBrush(this.ColorAtTarget); + this.BrushAtFromTarget = new SolidBrush(this.ColorAtFromTarget); + this.BrushAtTo = new SolidBrush(this.ColorAtTo); + this.BrushListBackcolor = new SolidBrush(this.ColorListBackcolor); + } + + public void Dispose() + { + if (this.IsDisposed) + return; + + this.FontUnread.Dispose(); + this.FontReaded.Dispose(); + this.FontDetail.Dispose(); + this.FontInputFont.Dispose(); + this.BrushSelf.Dispose(); + this.BrushAtSelf.Dispose(); + this.BrushTarget.Dispose(); + this.BrushAtTarget.Dispose(); + this.BrushAtFromTarget.Dispose(); + this.BrushAtTo.Dispose(); + this.BrushListBackcolor.Dispose(); + + this.IsDisposed = true; + } + + public static void ApplyGlobalUIFont(SettingLocal settingLocal) + { + var font = settingLocal.FontUIGlobal; + if (font != null) + OTBaseForm.GlobalFont = font; + } + } +} diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index f69803900..9466c56d1 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -157,72 +157,7 @@ public partial class TweenMain : OTBaseForm public HashtagManage HashMgr = null!; // 表示フォント、色、アイコン - - /// 未読用フォント - private Font fntUnread = null!; - - /// 未読用文字色 - private Color clUnread; - - /// 既読用フォント - private Font fntReaded = null!; - - /// 既読用文字色 - private Color clReaded; - - /// Fav用文字色 - private Color clFav; - - /// 片思い用文字色 - private Color clOWL; - - /// Retweet用文字色 - private Color clRetweet; - - /// 選択中の行用文字色 - private readonly Color clHighLight = Color.FromKnownColor(KnownColor.HighlightText); - - /// 発言詳細部用フォント - private Font fntDetail = null!; - - /// 発言詳細部用色 - private Color clDetail; - - /// 発言詳細部用リンク文字色 - private Color clDetailLink; - - /// 発言詳細部用背景色 - private Color clDetailBackcolor; - - /// 自分の発言用背景色 - private Color clSelf; - - /// 自分宛返信用背景色 - private Color clAtSelf; - - /// 選択発言者の他の発言用背景色 - private Color clTarget; - - /// 選択発言中の返信先用背景色 - private Color clAtTarget; - - /// 選択発言者への返信発言用背景色 - private Color clAtFromTarget; - - /// 選択発言の唯一@先 - private Color clAtTo; - - /// リスト部通常発言背景色 - private Color clListBackcolor; - - /// 入力欄背景色 - private Color clInputBackcolor; - - /// 入力欄文字色 - private Color clInputFont; - - /// 入力欄フォント - private Font fntInputFont = null!; + private ThemeManager themeManager; /// アイコン画像リスト private readonly ImageCache iconCache; @@ -251,13 +186,6 @@ public partial class TweenMain : OTBaseForm // 以下DrawItem関連 private readonly SolidBrush brsHighLight = new(Color.FromKnownColor(KnownColor.Highlight)); - private SolidBrush brsBackColorMine = null!; - private SolidBrush brsBackColorAt = null!; - private SolidBrush brsBackColorYou = null!; - private SolidBrush brsBackColorAtYou = null!; - private SolidBrush brsBackColorAtFromTarget = null!; - private SolidBrush brsBackColorAtTo = null!; - private SolidBrush brsBackColorNone = null!; /// Listにフォーカスないときの選択行の背景色 private readonly SolidBrush brsDeactiveSelection = new(Color.FromKnownColor(KnownColor.ButtonFace)); @@ -428,13 +356,7 @@ protected override void Dispose(bool disposing) this.urlDialog.Dispose(); this.listViewImageList.Dispose(); this.brsHighLight.Dispose(); - this.brsBackColorMine?.Dispose(); - this.brsBackColorAt?.Dispose(); - this.brsBackColorYou?.Dispose(); - this.brsBackColorAtYou?.Dispose(); - this.brsBackColorAtFromTarget?.Dispose(); - this.brsBackColorAtTo?.Dispose(); - this.brsBackColorNone?.Dispose(); + this.themeManager.Dispose(); this.brsDeactiveSelection?.Dispose(); this.sfTab.Dispose(); @@ -636,8 +558,6 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter this.hookGlobalHotkey = new HookGlobalHotkey(this); - this.tweetDetailsView.Owner = this; - this.hookGlobalHotkey.HotkeyPressed += this.HookGlobalHotkey_HotkeyPressed; this.gh.NotifyClicked += this.GrowlHelper_Callback; @@ -674,14 +594,6 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter // 現在の DPI と設定保存時の DPI との比を取得する var configScaleFactor = this.settings.Local.GetConfigScaleFactor(this.CurrentAutoScaleDimensions); - // UIフォント設定 - var fontUIGlobal = this.settings.Local.FontUIGlobal; - if (fontUIGlobal != null) - { - OTBaseForm.GlobalFont = fontUIGlobal; - this.Font = fontUIGlobal; - } - // 認証関連 this.tw.Initialize(this.settings.Common.Token, this.settings.Common.TokenSecret, this.settings.Common.UserName, this.settings.Common.UserId); @@ -747,39 +659,9 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter this.settings.Common.HashIsNotAddToAtReply); if (!MyCommon.IsNullOrEmpty(this.HashMgr.UseHash) && this.HashMgr.IsPermanent) this.HashStripSplitButton.Text = this.HashMgr.UseHash; - // アイコンリスト作成 - this.tweetDetailsView.IconCache = this.iconCache; - // フォント&文字色&背景色保持 - this.fntUnread = this.settings.Local.FontUnread; - this.clUnread = this.settings.Local.ColorUnread; - this.fntReaded = this.settings.Local.FontRead; - this.clReaded = this.settings.Local.ColorRead; - this.clFav = this.settings.Local.ColorFav; - this.clOWL = this.settings.Local.ColorOWL; - this.clRetweet = this.settings.Local.ColorRetweet; - this.fntDetail = this.settings.Local.FontDetail; - this.clDetail = this.settings.Local.ColorDetail; - this.clDetailLink = this.settings.Local.ColorDetailLink; - this.clDetailBackcolor = this.settings.Local.ColorDetailBackcolor; - this.clSelf = this.settings.Local.ColorSelf; - this.clAtSelf = this.settings.Local.ColorAtSelf; - this.clTarget = this.settings.Local.ColorTarget; - this.clAtTarget = this.settings.Local.ColorAtTarget; - this.clAtFromTarget = this.settings.Local.ColorAtFromTarget; - this.clAtTo = this.settings.Local.ColorAtTo; - this.clListBackcolor = this.settings.Local.ColorListBackcolor; - this.clInputBackcolor = this.settings.Local.ColorInputBackcolor; - this.clInputFont = this.settings.Local.ColorInputFont; - this.fntInputFont = this.settings.Local.FontInputFont; - - this.brsBackColorMine = new SolidBrush(this.clSelf); - this.brsBackColorAt = new SolidBrush(this.clAtSelf); - this.brsBackColorYou = new SolidBrush(this.clTarget); - this.brsBackColorAtYou = new SolidBrush(this.clAtTarget); - this.brsBackColorAtFromTarget = new SolidBrush(this.clAtFromTarget); - this.brsBackColorAtTo = new SolidBrush(this.clAtTo); - this.brsBackColorNone = new SolidBrush(this.clListBackcolor); + this.themeManager = new(this.settings.Local); + this.tweetDetailsView.Initialize(this, this.iconCache, this.themeManager); // StringFormatオブジェクトへの事前設定 this.sfTab.Alignment = StringAlignment.Center; @@ -850,8 +732,8 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter this.PlaySoundMenuItem.Checked = this.settings.Common.PlaySound; this.PlaySoundFileMenuItem.Checked = this.settings.Common.PlaySound; // 入力欄 - this.StatusText.Font = this.fntInputFont; - this.StatusText.ForeColor = this.clInputFont; + this.StatusText.Font = this.themeManager.FontInputFont; + this.StatusText.ForeColor = this.themeManager.ColorInputFont; // SplitContainer2.Panel2MinSize を一行表示の入力欄の高さに合わせる (MS UI Gothic 12pt (96dpi) の場合は 19px) this.StatusText.Multiline = false; // this.settings.Local.StatusMultiline の設定は後で反映される @@ -999,13 +881,16 @@ private void InitDetailHtmlFormat() { var htmlTemplate = this.settings.Common.IsMonospace ? DetailHtmlFormatTemplateMono : DetailHtmlFormatTemplateNormal; + static string ColorToRGBString(Color color) + => $"{color.R},{color.G},{color.B}"; + this.detailHtmlFormatPreparedTemplate = htmlTemplate - .Replace("%FONT_FAMILY%", this.fntDetail.Name) - .Replace("%FONT_SIZE%", this.fntDetail.Size.ToString()) - .Replace("%FONT_COLOR%", $"{this.clDetail.R},{this.clDetail.G},{this.clDetail.B}") - .Replace("%LINK_COLOR%", $"{this.clDetailLink.R},{this.clDetailLink.G},{this.clDetailLink.B}") - .Replace("%BG_COLOR%", $"{this.clDetailBackcolor.R},{this.clDetailBackcolor.G},{this.clDetailBackcolor.B}") - .Replace("%BG_REPLY_COLOR%", $"{this.clAtTo.R}, {this.clAtTo.G}, {this.clAtTo.B}"); + .Replace("%FONT_FAMILY%", this.themeManager.FontDetail.Name) + .Replace("%FONT_SIZE%", this.themeManager.FontDetail.Size.ToString()) + .Replace("%FONT_COLOR%", ColorToRGBString(this.themeManager.ColorDetail)) + .Replace("%LINK_COLOR%", ColorToRGBString(this.themeManager.ColorDetailLink)) + .Replace("%BG_COLOR%", ColorToRGBString(this.themeManager.ColorDetailBackcolor)) + .Replace("%BG_REPLY_COLOR%", ColorToRGBString(this.themeManager.ColorAtTo)); } private void ListTab_DrawItem(object sender, DrawItemEventArgs e) @@ -1681,12 +1566,12 @@ private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post, D // フォント if (read) { - fnt = this.fntReaded; + fnt = this.themeManager.FontReaded; star = ""; } else { - fnt = this.fntUnread; + fnt = this.themeManager.FontUnread; star = "★"; } if (item.SubItems[5].Text != star) @@ -1695,15 +1580,15 @@ private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post, D // 文字色 Color cl; if (post.IsFav) - cl = this.clFav; + cl = this.themeManager.ColorFav; else if (post.RetweetedId != null) - cl = this.clRetweet; + cl = this.themeManager.ColorRetweet; else if (post.IsOwl && (post.IsDm || this.settings.Common.OneWayLove)) - cl = this.clOWL; + cl = this.themeManager.ColorOWL; else if (read || !this.settings.Common.UseUnreadStyle) - cl = this.clReaded; + cl = this.themeManager.ColorRead; else - cl = this.clUnread; + cl = this.themeManager.ColorUnread; if (dList == null || item.Index == -1) { @@ -1772,25 +1657,25 @@ private Color JudgeColor(PostClass basePost, PostClass targetPost) Color cl; if (targetPost.StatusId == basePost.InReplyToStatusId) // @先 - cl = this.clAtTo; + cl = this.themeManager.ColorAtTo; else if (targetPost.IsMe) // 自分=発言者 - cl = this.clSelf; + cl = this.themeManager.ColorSelf; else if (targetPost.IsReply) // 自分宛返信 - cl = this.clAtSelf; + cl = this.themeManager.ColorAtSelf; else if (basePost.ReplyToList.Any(x => x.UserId == targetPost.UserId)) // 返信先 - cl = this.clAtFromTarget; + cl = this.themeManager.ColorAtFromTarget; else if (targetPost.ReplyToList.Any(x => x.UserId == basePost.UserId)) // その人への返信 - cl = this.clAtTarget; + cl = this.themeManager.ColorAtTarget; else if (targetPost.UserId == basePost.UserId) // 発言者 - cl = this.clTarget; + cl = this.themeManager.ColorTarget; else // その他 - cl = this.clListBackcolor; + cl = this.themeManager.ColorListBackcolor; return cl; } @@ -3313,47 +3198,19 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) this.NotifyFileMenuItem.Checked = this.settings.Common.NewAllPop; this.PlaySoundMenuItem.Checked = this.settings.Common.PlaySound; this.PlaySoundFileMenuItem.Checked = this.settings.Common.PlaySound; - this.fntUnread = this.settings.Local.FontUnread; - this.clUnread = this.settings.Local.ColorUnread; - this.fntReaded = this.settings.Local.FontRead; - this.clReaded = this.settings.Local.ColorRead; - this.clFav = this.settings.Local.ColorFav; - this.clOWL = this.settings.Local.ColorOWL; - this.clRetweet = this.settings.Local.ColorRetweet; - this.fntDetail = this.settings.Local.FontDetail; - this.clDetail = this.settings.Local.ColorDetail; - this.clDetailLink = this.settings.Local.ColorDetailLink; - this.clDetailBackcolor = this.settings.Local.ColorDetailBackcolor; - this.clSelf = this.settings.Local.ColorSelf; - this.clAtSelf = this.settings.Local.ColorAtSelf; - this.clTarget = this.settings.Local.ColorTarget; - this.clAtTarget = this.settings.Local.ColorAtTarget; - this.clAtFromTarget = this.settings.Local.ColorAtFromTarget; - this.clAtTo = this.settings.Local.ColorAtTo; - this.clListBackcolor = this.settings.Local.ColorListBackcolor; - this.clInputBackcolor = this.settings.Local.ColorInputBackcolor; - this.clInputFont = this.settings.Local.ColorInputFont; - this.fntInputFont = this.settings.Local.FontInputFont; - this.brsBackColorMine.Dispose(); - this.brsBackColorAt.Dispose(); - this.brsBackColorYou.Dispose(); - this.brsBackColorAtYou.Dispose(); - this.brsBackColorAtFromTarget.Dispose(); - this.brsBackColorAtTo.Dispose(); - this.brsBackColorNone.Dispose(); - this.brsBackColorMine = new SolidBrush(this.clSelf); - this.brsBackColorAt = new SolidBrush(this.clAtSelf); - this.brsBackColorYou = new SolidBrush(this.clTarget); - this.brsBackColorAtYou = new SolidBrush(this.clAtTarget); - this.brsBackColorAtFromTarget = new SolidBrush(this.clAtFromTarget); - this.brsBackColorAtTo = new SolidBrush(this.clAtTo); - this.brsBackColorNone = new SolidBrush(this.clListBackcolor); + + var newTheme = new ThemeManager(this.settings.Local); + (var oldTheme, this.themeManager) = (this.themeManager, newTheme); + this.tweetDetailsView.Theme = this.themeManager; + oldTheme.Dispose(); try { - if (this.StatusText.Focused) this.StatusText.BackColor = this.clInputBackcolor; - this.StatusText.Font = this.fntInputFont; - this.StatusText.ForeColor = this.clInputFont; + if (this.StatusText.Focused) + this.StatusText.BackColor = this.themeManager.ColorInputBackcolor; + + this.StatusText.Font = this.themeManager.FontInputFont; + this.StatusText.ForeColor = this.themeManager.ColorInputFont; } catch (Exception ex) { @@ -3406,8 +3263,8 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) using (ControlTransaction.Update(lst)) { lst.GridLines = this.settings.Common.ShowGrid; - lst.Font = this.fntReaded; - lst.BackColor = this.clListBackcolor; + lst.Font = this.themeManager.FontReaded; + lst.BackColor = this.themeManager.ColorListBackcolor; if (this.iconCol != oldIconCol) this.ResetColumns(lst); @@ -3812,8 +3669,8 @@ public bool AddNewTab(TabModel tab, bool startup) listCustom.View = View.Details; listCustom.OwnerDraw = true; listCustom.VirtualMode = true; - listCustom.Font = this.fntReaded; - listCustom.BackColor = this.clListBackcolor; + listCustom.Font = this.themeManager.FontReaded; + listCustom.BackColor = this.themeManager.ColorListBackcolor; listCustom.GridLines = this.settings.Common.ShowGrid; listCustom.AllowDrop = true; @@ -4180,7 +4037,7 @@ private void StatusText_TextChanged(object sender, EventArgs e) } else { - this.StatusText.ForeColor = this.clInputFont; + this.StatusText.ForeColor = this.themeManager.ColorInputFont; } this.StatusText.AccessibleDescription = string.Format(Properties.Resources.StatusText_AccessibleDescription, pLen); @@ -4586,23 +4443,23 @@ private void MyList_DrawItem(object sender, DrawListViewItemEventArgs e) if (e.State == 0) return; e.DrawDefault = false; - SolidBrush brs2; + Brush brs2; if (!e.Item.Selected) // e.ItemStateでうまく判定できない??? { - if (e.Item.BackColor == this.clSelf) - brs2 = this.brsBackColorMine; - else if (e.Item.BackColor == this.clAtSelf) - brs2 = this.brsBackColorAt; - else if (e.Item.BackColor == this.clTarget) - brs2 = this.brsBackColorYou; - else if (e.Item.BackColor == this.clAtTarget) - brs2 = this.brsBackColorAtYou; - else if (e.Item.BackColor == this.clAtFromTarget) - brs2 = this.brsBackColorAtFromTarget; - else if (e.Item.BackColor == this.clAtTo) - brs2 = this.brsBackColorAtTo; + if (e.Item.BackColor == this.themeManager.ColorSelf) + brs2 = this.themeManager.BrushSelf; + else if (e.Item.BackColor == this.themeManager.ColorAtSelf) + brs2 = this.themeManager.BrushAtSelf; + else if (e.Item.BackColor == this.themeManager.ColorTarget) + brs2 = this.themeManager.BrushTarget; + else if (e.Item.BackColor == this.themeManager.ColorAtTarget) + brs2 = this.themeManager.BrushAtTarget; + else if (e.Item.BackColor == this.themeManager.ColorAtFromTarget) + brs2 = this.themeManager.BrushAtFromTarget; + else if (e.Item.BackColor == this.themeManager.ColorAtTo) + brs2 = this.themeManager.BrushAtTo; else - brs2 = this.brsBackColorNone; + brs2 = this.themeManager.BrushListBackcolor; } else { @@ -4654,8 +4511,8 @@ private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) if (rct.Width > 0) { var color = (!e.Item.Selected) ? e.Item.ForeColor : // 選択されていない行 - ((Control)sender).Focused ? this.clHighLight : // 選択中の行 - this.clUnread; + ((Control)sender).Focused ? this.themeManager.ColorHighLight : // 選択中の行 + this.themeManager.ColorUnread; if (this.iconCol) { @@ -6726,14 +6583,11 @@ private void StatusText_Enter(object sender, EventArgs e) { // フォーカスの戻り先を StatusText に設定 this.Tag = this.StatusText; - this.StatusText.BackColor = this.clInputBackcolor; + this.StatusText.BackColor = this.themeManager.ColorInputBackcolor; } public Color InputBackColor - { - get => this.clInputBackcolor; - set => this.clInputBackcolor = value; - } + => this.themeManager.ColorInputBackcolor; private void StatusText_Leave(object sender, EventArgs e) { @@ -6836,28 +6690,6 @@ private void SaveConfigsLocal() this.settings.Local.StatusMultiline = this.StatusText.Multiline; this.settings.Local.StatusTextHeight = this.mySpDis2; - this.settings.Local.FontUnread = this.fntUnread; - this.settings.Local.ColorUnread = this.clUnread; - this.settings.Local.FontRead = this.fntReaded; - this.settings.Local.ColorRead = this.clReaded; - this.settings.Local.FontDetail = this.fntDetail; - this.settings.Local.ColorDetail = this.clDetail; - this.settings.Local.ColorDetailBackcolor = this.clDetailBackcolor; - this.settings.Local.ColorDetailLink = this.clDetailLink; - this.settings.Local.ColorFav = this.clFav; - this.settings.Local.ColorOWL = this.clOWL; - this.settings.Local.ColorRetweet = this.clRetweet; - this.settings.Local.ColorSelf = this.clSelf; - this.settings.Local.ColorAtSelf = this.clAtSelf; - this.settings.Local.ColorTarget = this.clTarget; - this.settings.Local.ColorAtTarget = this.clAtTarget; - this.settings.Local.ColorAtFromTarget = this.clAtFromTarget; - this.settings.Local.ColorAtTo = this.clAtTo; - this.settings.Local.ColorListBackcolor = this.clListBackcolor; - this.settings.Local.ColorInputBackcolor = this.clInputBackcolor; - this.settings.Local.ColorInputFont = this.clInputFont; - this.settings.Local.FontInputFont = this.fntInputFont; - if (this.ignoreConfigSave) return; this.settings.SaveLocal(); } diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index ccbb9f163..cc0fc0822 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -47,10 +47,12 @@ namespace OpenTween { public partial class TweetDetailsView : UserControl { - public TweenMain Owner { get; set; } = null!; + private TweenMain Owner + => this.owner ?? throw this.NotInitializedException(); /// プロフィール画像のキャッシュ - public ImageCache IconCache { get; set; } = null!; + private ImageCache IconCache + => this.iconCache ?? throw this.NotInitializedException(); /// のダンプを表示するか public bool DumpPostClass { get; set; } @@ -58,6 +60,12 @@ public partial class TweetDetailsView : UserControl /// 現在表示中の発言 public PostClass? CurrentPost { get; private set; } + public ThemeManager Theme + { + get => this.themeManager ?? throw this.NotInitializedException(); + set => this.themeManager = value; + } + [DefaultValue(false)] public new bool TabStop { @@ -71,6 +79,10 @@ public partial class TweetDetailsView : UserControl /// 展開時の .StatusText を保持するフィールド private string postBrowserStatusText = ""; + private TweenMain? owner; + private ImageCache? iconCache; + private ThemeManager? themeManager; + public TweetDetailsView() { this.InitializeComponent(); @@ -87,6 +99,16 @@ public TweetDetailsView() this.PostBrowser.AllowWebBrowserDrop = false; // COMException を回避するため、ActiveX の初期化が終わってから設定する } + public void Initialize(TweenMain owner, ImageCache iconCache, ThemeManager themeManager) + { + this.owner = owner; + this.iconCache = iconCache; + this.themeManager = themeManager; + } + + private Exception NotInitializedException() + => new InvalidOperationException("Cannot call before initialization"); + public void ClearPostBrowser() => this.PostBrowser.DocumentText = this.Owner.CreateDetailHtml(""); @@ -129,11 +151,11 @@ public async Task ShowPostDetails(PostClass post) var nameForeColor = SystemColors.ControlText; if (post.IsOwl && (SettingManager.Instance.Common.OneWayLove || post.IsDm)) - nameForeColor = SettingManager.Instance.Local.ColorOWL; + nameForeColor = this.Theme.ColorOWL; if (post.RetweetedId != null) - nameForeColor = SettingManager.Instance.Local.ColorRetweet; + nameForeColor = this.Theme.ColorRetweet; if (post.IsFav) - nameForeColor = SettingManager.Instance.Local.ColorFav; + nameForeColor = this.Theme.ColorFav; this.AuthorNameLinkLabel.LinkColor = nameForeColor; this.AuthorNameLinkLabel.ActiveLinkColor = nameForeColor; @@ -219,9 +241,9 @@ public void ScrollDownPostBrowser(bool forward) if (tags.Count > 0) { if (forward) - tags[0].ScrollTop += SettingManager.Instance.Local.FontDetail.Height; + tags[0].ScrollTop += this.Theme.FontDetail.Height; else - tags[0].ScrollTop -= SettingManager.Instance.Local.FontDetail.Height; + tags[0].ScrollTop -= this.Theme.FontDetail.Height; } } @@ -234,9 +256,9 @@ public void PageDownPostBrowser(bool forward) if (tags.Count > 0) { if (forward) - tags[0].ScrollTop += this.PostBrowser.ClientRectangle.Height - SettingManager.Instance.Local.FontDetail.Height; + tags[0].ScrollTop += this.PostBrowser.ClientRectangle.Height - this.Theme.FontDetail.Height; else - tags[0].ScrollTop -= this.PostBrowser.ClientRectangle.Height - SettingManager.Instance.Local.FontDetail.Height; + tags[0].ScrollTop -= this.PostBrowser.ClientRectangle.Height - this.Theme.FontDetail.Height; } } From 0fe5c9bc852dc1b3e152040c8280b3387567947f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 9 Apr 2022 00:05:05 +0900 Subject: [PATCH 166/402] =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=AE=E5=80=A4=E3=81=8B=E3=82=89Font?= =?UTF-8?q?=E3=82=84Color=E3=82=92=E7=94=9F=E6=88=90=E3=81=99=E3=82=8B?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92ThemeManager=E3=81=AB=E7=A7=BB?= =?UTF-8?q?=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/ThemeManagerTest.cs | 74 ++++++ OpenTween/Setting/Panel/FontPanel.Designer.cs | 13 - OpenTween/Setting/Panel/FontPanel.cs | 99 +++++--- .../Setting/Panel/FontPanel2.Designer.cs | 13 - OpenTween/Setting/Panel/FontPanel2.cs | 94 ++++--- OpenTween/Setting/SettingLocal.cs | 235 ++---------------- OpenTween/ThemeManager.cs | 141 +++++++++-- 7 files changed, 330 insertions(+), 339 deletions(-) create mode 100644 OpenTween.Tests/ThemeManagerTest.cs diff --git a/OpenTween.Tests/ThemeManagerTest.cs b/OpenTween.Tests/ThemeManagerTest.cs new file mode 100644 index 000000000..bcdad67c4 --- /dev/null +++ b/OpenTween.Tests/ThemeManagerTest.cs @@ -0,0 +1,74 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System.Drawing; +using Xunit; + +namespace OpenTween +{ + public class ThemeManagerTest + { + [Fact] + public void FontDefaultTest() + { + var settings = new SettingLocal(); + using var themeManager = new ThemeManager(settings); + Assert.True(themeManager.FontDetail.IsSystemFont); + Assert.Equal(nameof(SystemFonts.DefaultFont), themeManager.FontDetail.SystemFontName); + } + + [Fact] + public void FontCustomTest() + { + var settings = new SettingLocal + { + FontDetailStr = "Arial, 9pt", + }; + using var themeManager = new ThemeManager(settings); + Assert.False(themeManager.FontDetail.IsSystemFont); + Assert.Equal("Arial", themeManager.FontDetail.OriginalFontName); + Assert.Equal(9, themeManager.FontDetail.SizeInPoints); + } + + [Fact] + public void ColorDefaultTest() + { + var settings = new SettingLocal(); + using var themeManager = new ThemeManager(settings); + Assert.True(themeManager.ColorDetail.IsSystemColor); + Assert.Equal(nameof(KnownColor.ControlText), themeManager.ColorDetail.Name); + } + + [Fact] + public void ColorCustomTest() + { + var settings = new SettingLocal + { + ColorDetailStr = "0, 100, 200", + }; + using var themeManager = new ThemeManager(settings); + Assert.False(themeManager.ColorDetail.IsSystemColor); + Assert.Equal(0, themeManager.ColorDetail.R); + Assert.Equal(100, themeManager.ColorDetail.G); + Assert.Equal(200, themeManager.ColorDetail.B); + } + } +} diff --git a/OpenTween/Setting/Panel/FontPanel.Designer.cs b/OpenTween/Setting/Panel/FontPanel.Designer.cs index 0d94170a9..b9a636691 100644 --- a/OpenTween/Setting/Panel/FontPanel.Designer.cs +++ b/OpenTween/Setting/Panel/FontPanel.Designer.cs @@ -7,19 +7,6 @@ partial class FontPanel /// private System.ComponentModel.IContainer components = null; - /// - /// 使用中のリソースをすべてクリーンアップします。 - /// - /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - #region コンポーネント デザイナーで生成されたコード /// diff --git a/OpenTween/Setting/Panel/FontPanel.cs b/OpenTween/Setting/Panel/FontPanel.cs index 7c99f772d..1c9fcbb10 100644 --- a/OpenTween/Setting/Panel/FontPanel.cs +++ b/OpenTween/Setting/Panel/FontPanel.cs @@ -39,62 +39,70 @@ namespace OpenTween.Setting.Panel { public partial class FontPanel : SettingPanelBase { + private readonly ThemeManager defaultTheme = new(new()); + private ThemeManager currentTheme = new(new()); + public FontPanel() => this.InitializeComponent(); public void LoadConfig(SettingLocal settingLocal) { - this.lblListFont.Font = settingLocal.FontRead; - this.lblUnread.Font = settingLocal.FontUnread; - this.lblUnread.ForeColor = settingLocal.ColorUnread; - this.lblListFont.ForeColor = settingLocal.ColorRead; - this.lblFav.ForeColor = settingLocal.ColorFav; - this.lblOWL.ForeColor = settingLocal.ColorOWL; - this.lblRetweet.ForeColor = settingLocal.ColorRetweet; - this.lblDetail.Font = settingLocal.FontDetail; - this.lblDetailBackcolor.BackColor = settingLocal.ColorDetailBackcolor; - this.lblDetail.ForeColor = settingLocal.ColorDetail; - this.lblDetailLink.ForeColor = settingLocal.ColorDetailLink; + this.UpdateTheme(settingLocal); + + this.lblListFont.Font = this.currentTheme.FontReaded; + this.lblUnread.Font = this.currentTheme.FontUnread; + this.lblUnread.ForeColor = this.currentTheme.ColorUnread; + this.lblListFont.ForeColor = this.currentTheme.ColorRead; + this.lblFav.ForeColor = this.currentTheme.ColorFav; + this.lblOWL.ForeColor = this.currentTheme.ColorOWL; + this.lblRetweet.ForeColor = this.currentTheme.ColorRetweet; + this.lblDetail.Font = this.currentTheme.FontDetail; + this.lblDetailBackcolor.BackColor = this.currentTheme.ColorDetailBackcolor; + this.lblDetail.ForeColor = this.currentTheme.ColorDetail; + this.lblDetailLink.ForeColor = this.currentTheme.ColorDetailLink; this.checkBoxUseTwemoji.Checked = settingLocal.UseTwemoji; } public void SaveConfig(SettingLocal settingLocal) { - settingLocal.FontUnread = this.lblUnread.Font; // 未使用 - settingLocal.ColorUnread = this.lblUnread.ForeColor; - settingLocal.FontRead = this.lblListFont.Font; // リストフォントとして使用 - settingLocal.ColorRead = this.lblListFont.ForeColor; - settingLocal.ColorFav = this.lblFav.ForeColor; - settingLocal.ColorOWL = this.lblOWL.ForeColor; - settingLocal.ColorRetweet = this.lblRetweet.ForeColor; - settingLocal.FontDetail = this.lblDetail.Font; - settingLocal.ColorDetailBackcolor = this.lblDetailBackcolor.BackColor; - settingLocal.ColorDetail = this.lblDetail.ForeColor; - settingLocal.ColorDetailLink = this.lblDetailLink.ForeColor; + var fontConverter = new FontConverter(); + var colorConverter = new ColorConverter(); + + settingLocal.FontUnreadStr = ThemeManager.ConvertFontToString(fontConverter, this.lblUnread.Font, this.defaultTheme.FontUnread); // 未使用 + settingLocal.ColorUnreadStr = ThemeManager.ConvertColorToString(colorConverter, this.lblUnread.ForeColor, this.defaultTheme.ColorUnread); + settingLocal.FontReadStr = ThemeManager.ConvertFontToString(fontConverter, this.lblListFont.Font, this.defaultTheme.FontReaded); // リストフォントとして使用 + settingLocal.ColorReadStr = ThemeManager.ConvertColorToString(colorConverter, this.lblListFont.ForeColor, this.defaultTheme.ColorRead); + settingLocal.ColorFavStr = ThemeManager.ConvertColorToString(colorConverter, this.lblFav.ForeColor, this.defaultTheme.ColorFav); + settingLocal.ColorOWLStr = ThemeManager.ConvertColorToString(colorConverter, this.lblOWL.ForeColor, this.defaultTheme.ColorOWL); + settingLocal.ColorRetweetStr = ThemeManager.ConvertColorToString(colorConverter, this.lblRetweet.ForeColor, this.defaultTheme.ColorRetweet); + settingLocal.FontDetailStr = ThemeManager.ConvertFontToString(fontConverter, this.lblDetail.Font, this.defaultTheme.FontDetail); + settingLocal.ColorDetailBackcolorStr = ThemeManager.ConvertColorToString(colorConverter, this.lblDetailBackcolor.BackColor, this.defaultTheme.ColorDetailBackcolor); + settingLocal.ColorDetailStr = ThemeManager.ConvertColorToString(colorConverter, this.lblDetail.ForeColor, this.defaultTheme.ColorDetail); + settingLocal.ColorDetailLinkStr = ThemeManager.ConvertColorToString(colorConverter, this.lblDetailLink.ForeColor, this.defaultTheme.ColorDetailLink); settingLocal.UseTwemoji = this.checkBoxUseTwemoji.Checked; } - private void ButtonBackToDefaultFontColor_Click(object sender, EventArgs e) + private void UpdateTheme(SettingLocal settingLocal) { - this.lblUnread.ForeColor = SystemColors.ControlText; - this.lblUnread.Font = new Font(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline); - - this.lblListFont.ForeColor = System.Drawing.SystemColors.ControlText; - this.lblListFont.Font = System.Drawing.SystemFonts.DefaultFont; + var newTheme = new ThemeManager(settingLocal); + (var oldTheme, this.currentTheme) = (this.currentTheme, newTheme); + oldTheme.Dispose(); + } - this.lblDetail.ForeColor = Color.FromKnownColor(System.Drawing.KnownColor.ControlText); - this.lblDetail.Font = System.Drawing.SystemFonts.DefaultFont; + private void ButtonBackToDefaultFontColor_Click(object sender, EventArgs e) + { + this.lblUnread.ForeColor = this.defaultTheme.ColorUnread; + this.lblUnread.Font = this.defaultTheme.FontUnread; + this.lblListFont.ForeColor = this.defaultTheme.ColorRead; + this.lblListFont.Font = this.defaultTheme.FontReaded; + this.lblDetail.ForeColor = this.defaultTheme.ColorDetail; + this.lblDetail.Font = this.defaultTheme.FontDetail; this.checkBoxUseTwemoji.Checked = true; - - this.lblFav.ForeColor = Color.FromKnownColor(System.Drawing.KnownColor.Red); - - this.lblOWL.ForeColor = Color.FromKnownColor(System.Drawing.KnownColor.Blue); - - this.lblDetailBackcolor.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.Window); - - this.lblDetailLink.ForeColor = Color.FromKnownColor(System.Drawing.KnownColor.Blue); - - this.lblRetweet.ForeColor = Color.FromKnownColor(System.Drawing.KnownColor.Green); + this.lblFav.ForeColor = this.defaultTheme.ColorFav; + this.lblOWL.ForeColor = this.defaultTheme.ColorOWL; + this.lblDetailBackcolor.BackColor = this.defaultTheme.ColorDetailBackcolor; + this.lblDetailLink.ForeColor = this.defaultTheme.ColorDetailLink; + this.lblRetweet.ForeColor = this.defaultTheme.ColorRetweet; } private void BtnListFont_Click(object sender, EventArgs e) @@ -120,5 +128,16 @@ private void BtnDetailLink_Click(object sender, EventArgs e) private void BtnDetailBack_Click(object sender, EventArgs e) => this.ShowBackColorDialog(this.lblDetailBackcolor); + + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.components?.Dispose(); + this.defaultTheme.Dispose(); + this.currentTheme.Dispose(); + } + base.Dispose(disposing); + } } } diff --git a/OpenTween/Setting/Panel/FontPanel2.Designer.cs b/OpenTween/Setting/Panel/FontPanel2.Designer.cs index 8da155251..484aa32b5 100644 --- a/OpenTween/Setting/Panel/FontPanel2.Designer.cs +++ b/OpenTween/Setting/Panel/FontPanel2.Designer.cs @@ -7,19 +7,6 @@ partial class FontPanel2 /// private System.ComponentModel.IContainer components = null; - /// - /// 使用中のリソースをすべてクリーンアップします。 - /// - /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - #region コンポーネント デザイナーで生成されたコード /// diff --git a/OpenTween/Setting/Panel/FontPanel2.cs b/OpenTween/Setting/Panel/FontPanel2.cs index a515a4a19..f490b7230 100644 --- a/OpenTween/Setting/Panel/FontPanel2.cs +++ b/OpenTween/Setting/Panel/FontPanel2.cs @@ -39,57 +39,64 @@ namespace OpenTween.Setting.Panel { public partial class FontPanel2 : SettingPanelBase { + private readonly ThemeManager defaultTheme = new(new()); + private ThemeManager currentTheme = new(new()); + public FontPanel2() => this.InitializeComponent(); public void LoadConfig(SettingLocal settingLocal) { - this.lblSelf.BackColor = settingLocal.ColorSelf; - this.lblAtSelf.BackColor = settingLocal.ColorAtSelf; - this.lblTarget.BackColor = settingLocal.ColorTarget; - this.lblAtTarget.BackColor = settingLocal.ColorAtTarget; - this.lblAtFromTarget.BackColor = settingLocal.ColorAtFromTarget; - this.lblAtTo.BackColor = settingLocal.ColorAtTo; - this.lblInputBackcolor.BackColor = settingLocal.ColorInputBackcolor; - this.lblInputFont.ForeColor = settingLocal.ColorInputFont; - this.lblInputFont.Font = settingLocal.FontInputFont; - this.lblListBackcolor.BackColor = settingLocal.ColorListBackcolor; + this.UpdateTheme(settingLocal); + + this.lblSelf.BackColor = this.currentTheme.ColorSelf; + this.lblAtSelf.BackColor = this.currentTheme.ColorAtSelf; + this.lblTarget.BackColor = this.currentTheme.ColorTarget; + this.lblAtTarget.BackColor = this.currentTheme.ColorAtTarget; + this.lblAtFromTarget.BackColor = this.currentTheme.ColorAtFromTarget; + this.lblAtTo.BackColor = this.currentTheme.ColorAtTo; + this.lblInputBackcolor.BackColor = this.currentTheme.ColorInputBackcolor; + this.lblInputFont.ForeColor = this.currentTheme.ColorInputFont; + this.lblInputFont.Font = this.currentTheme.FontInputFont; + this.lblListBackcolor.BackColor = this.currentTheme.ColorListBackcolor; } public void SaveConfig(SettingLocal settingLocal) { - settingLocal.ColorSelf = this.lblSelf.BackColor; - settingLocal.ColorAtSelf = this.lblAtSelf.BackColor; - settingLocal.ColorTarget = this.lblTarget.BackColor; - settingLocal.ColorAtTarget = this.lblAtTarget.BackColor; - settingLocal.ColorAtFromTarget = this.lblAtFromTarget.BackColor; - settingLocal.ColorAtTo = this.lblAtTo.BackColor; - settingLocal.ColorInputBackcolor = this.lblInputBackcolor.BackColor; - settingLocal.ColorInputFont = this.lblInputFont.ForeColor; - settingLocal.ColorListBackcolor = this.lblListBackcolor.BackColor; - settingLocal.FontInputFont = this.lblInputFont.Font; + var fontConverter = new FontConverter(); + var colorConverter = new ColorConverter(); + + settingLocal.ColorSelfStr = ThemeManager.ConvertColorToString(colorConverter, this.lblSelf.BackColor, this.defaultTheme.ColorSelf); + settingLocal.ColorAtSelfStr = ThemeManager.ConvertColorToString(colorConverter, this.lblAtSelf.BackColor, this.defaultTheme.ColorAtSelf); + settingLocal.ColorTargetStr = ThemeManager.ConvertColorToString(colorConverter, this.lblTarget.BackColor, this.defaultTheme.ColorTarget); + settingLocal.ColorAtTargetStr = ThemeManager.ConvertColorToString(colorConverter, this.lblAtTarget.BackColor, this.defaultTheme.ColorAtTarget); + settingLocal.ColorAtFromTargetStr = ThemeManager.ConvertColorToString(colorConverter, this.lblAtFromTarget.BackColor, this.defaultTheme.ColorAtFromTarget); + settingLocal.ColorAtToStr = ThemeManager.ConvertColorToString(colorConverter, this.lblAtTo.BackColor, this.defaultTheme.ColorAtTo); + settingLocal.ColorInputBackcolorStr = ThemeManager.ConvertColorToString(colorConverter, this.lblInputBackcolor.BackColor, this.defaultTheme.ColorInputBackcolor); + settingLocal.ColorInputFontStr = ThemeManager.ConvertColorToString(colorConverter, this.lblInputFont.ForeColor, this.defaultTheme.ColorInputFont); + settingLocal.ColorListBackcolorStr = ThemeManager.ConvertColorToString(colorConverter, this.lblListBackcolor.BackColor, this.defaultTheme.ColorListBackcolor); + settingLocal.FontInputFontStr = ThemeManager.ConvertFontToString(fontConverter, this.lblInputFont.Font, this.defaultTheme.FontInputFont); } - private void ButtonBackToDefaultFontColor2_Click(object sender, EventArgs e) + private void UpdateTheme(SettingLocal settingLocal) { - this.lblInputFont.ForeColor = Color.FromKnownColor(System.Drawing.KnownColor.ControlText); - this.lblInputFont.Font = System.Drawing.SystemFonts.DefaultFont; - - this.lblSelf.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.AliceBlue); - - this.lblAtSelf.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.AntiqueWhite); - - this.lblTarget.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.LemonChiffon); - - this.lblAtTarget.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.LavenderBlush); - - this.lblAtFromTarget.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.Honeydew); - - this.lblInputBackcolor.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.LemonChiffon); - - this.lblAtTo.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.Pink); + var newTheme = new ThemeManager(settingLocal); + (var oldTheme, this.currentTheme) = (this.currentTheme, newTheme); + oldTheme.Dispose(); + } - this.lblListBackcolor.BackColor = Color.FromKnownColor(System.Drawing.KnownColor.Window); + private void ButtonBackToDefaultFontColor2_Click(object sender, EventArgs e) + { + this.lblInputFont.ForeColor = this.defaultTheme.ColorInputFont; + this.lblInputFont.Font = this.defaultTheme.FontInputFont; + this.lblSelf.BackColor = this.defaultTheme.ColorSelf; + this.lblAtSelf.BackColor = this.defaultTheme.ColorAtSelf; + this.lblTarget.BackColor = this.defaultTheme.ColorTarget; + this.lblAtTarget.BackColor = this.defaultTheme.ColorAtTarget; + this.lblAtFromTarget.BackColor = this.defaultTheme.ColorAtFromTarget; + this.lblInputBackcolor.BackColor = this.defaultTheme.ColorInputBackcolor; + this.lblAtTo.BackColor = this.defaultTheme.ColorAtTo; + this.lblListBackcolor.BackColor = this.defaultTheme.ColorListBackcolor; } private void BtnSelf_Click(object sender, EventArgs e) @@ -118,5 +125,16 @@ private void BtnInputBackcolor_Click(object sender, EventArgs e) private void BtnInputFont_Click(object sender, EventArgs e) => this.ShowFontDialog(this.lblInputFont); + + protected override void Dispose(bool disposing) + { + if (disposing) + { + this.components?.Dispose(); + this.defaultTheme.Dispose(); + this.currentTheme.Dispose(); + } + base.Dispose(disposing); + } } } diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index 3083a2a52..001a808e8 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -36,7 +36,7 @@ namespace OpenTween { - public class SettingLocal : SettingBase, IDisposable + public class SettingLocal : SettingBase { #region Settingクラス基本 public static SettingLocal Load() @@ -86,197 +86,47 @@ public void Save() public int StatusTextHeight = 38; public int PreviewDistance = -1; - [XmlIgnore] - public Font FontUnread = new(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline); - - public string FontUnreadStr - { - get => this.FontToString(this.FontUnread); - set => this.FontUnread = this.StringToFont(value); - } - - [XmlIgnore] - public Color ColorUnread = System.Drawing.SystemColors.ControlText; - - public string ColorUnreadStr - { - get => this.ColorToString(this.ColorUnread); - set => this.ColorUnread = this.StringToColor(value); - } - - [XmlIgnore] - public Font FontRead = System.Drawing.SystemFonts.DefaultFont; - - public string FontReadStr - { - get => this.FontToString(this.FontRead); - set => this.FontRead = this.StringToFont(value); - } - - [XmlIgnore] - public Color ColorRead = System.Drawing.SystemColors.ControlText; - - public string ColorReadStr - { - get => this.ColorToString(this.ColorRead); - set => this.ColorRead = this.StringToColor(value); - } - - [XmlIgnore] - public Color ColorFav = Color.FromKnownColor(System.Drawing.KnownColor.Red); - - public string ColorFavStr - { - get => this.ColorToString(this.ColorFav); - set => this.ColorFav = this.StringToColor(value); - } - - [XmlIgnore] - public Color ColorOWL = Color.FromKnownColor(System.Drawing.KnownColor.Blue); - - public string ColorOWLStr - { - get => this.ColorToString(this.ColorOWL); - set => this.ColorOWL = this.StringToColor(value); - } - - [XmlIgnore] - public Color ColorRetweet = Color.FromKnownColor(System.Drawing.KnownColor.Green); - - public string ColorRetweetStr - { - get => this.ColorToString(this.ColorRetweet); - set => this.ColorRetweet = this.StringToColor(value); - } - - [XmlIgnore] - public Font FontDetail = System.Drawing.SystemFonts.DefaultFont; - - public string FontDetailStr - { - get => this.FontToString(this.FontDetail); - set => this.FontDetail = this.StringToFont(value); - } - - [XmlIgnore] - public Color ColorSelf = Color.FromKnownColor(System.Drawing.KnownColor.AliceBlue); - - public string ColorSelfStr - { - get => this.ColorToString(this.ColorSelf); - set => this.ColorSelf = this.StringToColor(value); - } - - [XmlIgnore] - public Color ColorAtSelf = Color.FromKnownColor(System.Drawing.KnownColor.AntiqueWhite); - - public string ColorAtSelfStr - { - get => this.ColorToString(this.ColorAtSelf); - set => this.ColorAtSelf = this.StringToColor(value); - } - - [XmlIgnore] - public Color ColorTarget = Color.FromKnownColor(System.Drawing.KnownColor.LemonChiffon); - - public string ColorTargetStr - { - get => this.ColorToString(this.ColorTarget); - set => this.ColorTarget = this.StringToColor(value); - } + public string? FontUnreadStr { get; set; } - [XmlIgnore] - public Color ColorAtTarget = Color.FromKnownColor(System.Drawing.KnownColor.LavenderBlush); + public string? ColorUnreadStr { get; set; } - public string ColorAtTargetStr - { - get => this.ColorToString(this.ColorAtTarget); - set => this.ColorAtTarget = this.StringToColor(value); - } + public string? FontReadStr { get; set; } - [XmlIgnore] - public Color ColorAtFromTarget = Color.FromKnownColor(System.Drawing.KnownColor.Honeydew); + public string? ColorReadStr { get; set; } - public string ColorAtFromTargetStr - { - get => this.ColorToString(this.ColorAtFromTarget); - set => this.ColorAtFromTarget = this.StringToColor(value); - } - - [XmlIgnore] - public Color ColorAtTo = Color.FromKnownColor(System.Drawing.KnownColor.Pink); + public string? ColorFavStr { get; set; } - public string ColorAtToStr - { - get => this.ColorToString(this.ColorAtTo); - set => this.ColorAtTo = this.StringToColor(value); - } + public string? ColorOWLStr { get; set; } - [XmlIgnore] - public Color ColorInputBackcolor = Color.FromKnownColor(System.Drawing.KnownColor.LemonChiffon); + public string? ColorRetweetStr { get; set; } - public string ColorInputBackcolorStr - { - get => this.ColorToString(this.ColorInputBackcolor); - set => this.ColorInputBackcolor = this.StringToColor(value); - } + public string? FontDetailStr { get; set; } - [XmlIgnore] - public Color ColorInputFont = Color.FromKnownColor(System.Drawing.KnownColor.ControlText); + public string? ColorSelfStr { get; set; } - public string ColorInputFontStr - { - get => this.ColorToString(this.ColorInputFont); - set => this.ColorInputFont = this.StringToColor(value); - } + public string? ColorAtSelfStr { get; set; } - [XmlIgnore] - public Font FontInputFont = System.Drawing.SystemFonts.DefaultFont; + public string? ColorTargetStr { get; set; } - public string FontInputFontStr - { - get => this.FontToString(this.FontInputFont); - set => this.FontInputFont = this.StringToFont(value); - } + public string? ColorAtTargetStr { get; set; } - [XmlIgnore] - public Color ColorListBackcolor = Color.FromKnownColor(System.Drawing.KnownColor.Window); + public string? ColorAtFromTargetStr { get; set; } - public string ColorListBackcolorStr - { - get => this.ColorToString(this.ColorListBackcolor); - set => this.ColorListBackcolor = this.StringToColor(value); - } + public string? ColorAtToStr { get; set; } - [XmlIgnore] - public Color ColorDetailBackcolor = Color.FromKnownColor(System.Drawing.KnownColor.Window); + public string? ColorInputBackcolorStr { get; set; } - public string ColorDetailBackcolorStr - { - get => this.ColorToString(this.ColorDetailBackcolor); - set => this.ColorDetailBackcolor = this.StringToColor(value); - } + public string? ColorInputFontStr { get; set; } - [XmlIgnore] - public Color ColorDetail = Color.FromKnownColor(System.Drawing.KnownColor.ControlText); + public string? FontInputFontStr { get; set; } - public string ColorDetailStr - { - get => this.ColorToString(this.ColorDetail); - set => this.ColorDetail = this.StringToColor(value); - } + public string? ColorListBackcolorStr { get; set; } - [XmlIgnore] - public Color ColorDetailLink = Color.FromKnownColor(System.Drawing.KnownColor.Blue); + public string? ColorDetailBackcolorStr { get; set; } - public string ColorDetailLinkStr - { - get => this.ColorToString(this.ColorDetailLink); - set => this.ColorDetailLink = this.StringToColor(value); - } + public string? ColorDetailStr { get; set; } - [XmlIgnore] - public Font? FontUIGlobal = null; + public string? ColorDetailLinkStr { get; set; } /// /// [隠し設定] UI フォントを指定します @@ -284,11 +134,7 @@ public string ColorDetailLinkStr /// /// フォントによっては一部レイアウトが崩れるためこっそり追加 /// - public string? FontUIGlobalStr - { - get => this.FontUIGlobal != null ? this.FontToString(this.FontUIGlobal) : null; - set => this.FontUIGlobal = value != null ? this.StringToFont(value) : null; - } + public string? FontUIGlobalStr { get; set; } [XmlIgnore] public string ProxyPassword = ""; @@ -340,24 +186,6 @@ public string EncryptProxyPassword /// public bool UseTwemoji = true; - [XmlIgnore] - private readonly FontConverter fontConverter = new(); - - protected string FontToString(Font font) - => this.fontConverter.ConvertToString(font); - - protected Font StringToFont(string str) - => (Font)this.fontConverter.ConvertFromString(str); - - [XmlIgnore] - private readonly ColorConverter colorConverter = new(); - - protected string ColorToString(Color color) - => this.colorConverter.ConvertToString(color); - - protected Color StringToColor(string str) - => (Color)this.colorConverter.ConvertFromString(str); - /// /// 指定されたスケールと SettingLocal.ScaleDimension のスケールとの拡大比を返します /// @@ -365,22 +193,5 @@ public SizeF GetConfigScaleFactor(SizeF currentSizeDimension) => new( currentSizeDimension.Width / this.ScaleDimension.Width, currentSizeDimension.Height / this.ScaleDimension.Height); - - public void Dispose() - { - this.Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - this.FontUnread?.Dispose(); - this.FontRead?.Dispose(); - this.FontDetail?.Dispose(); - this.FontInputFont?.Dispose(); - } - } } } diff --git a/OpenTween/ThemeManager.cs b/OpenTween/ThemeManager.cs index 5bccfd487..9b1d118c3 100644 --- a/OpenTween/ThemeManager.cs +++ b/OpenTween/ThemeManager.cs @@ -117,29 +117,74 @@ public sealed class ThemeManager : IDisposable public ThemeManager(SettingLocal settingLocal) { - this.FontUnread = settingLocal.FontUnread; - this.FontReaded = settingLocal.FontRead; - this.FontDetail = settingLocal.FontDetail; - this.FontInputFont = settingLocal.FontInputFont; - - this.ColorUnread = settingLocal.ColorUnread; - this.ColorRead = settingLocal.ColorRead; - this.ColorFav = settingLocal.ColorFav; - this.ColorOWL = settingLocal.ColorOWL; - this.ColorRetweet = settingLocal.ColorRetweet; + var fontConverter = new FontConverter(); + + this.FontUnread = ConvertStringToFont(fontConverter, settingLocal.FontUnreadStr) + ?? new(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline); + + this.FontReaded = ConvertStringToFont(fontConverter, settingLocal.FontReadStr) + ?? SystemFonts.DefaultFont; + + this.FontDetail = ConvertStringToFont(fontConverter, settingLocal.FontDetailStr) + ?? SystemFonts.DefaultFont; + + this.FontInputFont = ConvertStringToFont(fontConverter, settingLocal.FontInputFontStr) + ?? SystemFonts.DefaultFont; + + var colorConverter = new ColorConverter(); + + this.ColorUnread = ConvertStringToColor(colorConverter, settingLocal.ColorUnreadStr) + ?? SystemColors.ControlText; + + this.ColorRead = ConvertStringToColor(colorConverter, settingLocal.ColorReadStr) + ?? SystemColors.ControlText; + + this.ColorFav = ConvertStringToColor(colorConverter, settingLocal.ColorFavStr) + ?? Color.FromKnownColor(KnownColor.Red); + + this.ColorOWL = ConvertStringToColor(colorConverter, settingLocal.ColorOWLStr) + ?? Color.FromKnownColor(KnownColor.Blue); + + this.ColorRetweet = ConvertStringToColor(colorConverter, settingLocal.ColorRetweetStr) + ?? Color.FromKnownColor(KnownColor.Green); + this.ColorHighLight = Color.FromKnownColor(KnownColor.HighlightText); - this.ColorDetail = settingLocal.ColorDetail; - this.ColorDetailLink = settingLocal.ColorDetailLink; - this.ColorDetailBackcolor = settingLocal.ColorDetailBackcolor; - this.ColorSelf = settingLocal.ColorSelf; - this.ColorAtSelf = settingLocal.ColorAtSelf; - this.ColorTarget = settingLocal.ColorTarget; - this.ColorAtTarget = settingLocal.ColorAtTarget; - this.ColorAtFromTarget = settingLocal.ColorAtFromTarget; - this.ColorAtTo = settingLocal.ColorAtTo; - this.ColorListBackcolor = settingLocal.ColorListBackcolor; - this.ColorInputBackcolor = settingLocal.ColorInputBackcolor; - this.ColorInputFont = settingLocal.ColorInputFont; + + this.ColorDetail = ConvertStringToColor(colorConverter, settingLocal.ColorDetailStr) + ?? Color.FromKnownColor(KnownColor.ControlText); + + this.ColorDetailLink = ConvertStringToColor(colorConverter, settingLocal.ColorDetailLinkStr) + ?? Color.FromKnownColor(KnownColor.Blue); + + this.ColorDetailBackcolor = ConvertStringToColor(colorConverter, settingLocal.ColorDetailBackcolorStr) + ?? Color.FromKnownColor(KnownColor.Window); + + this.ColorSelf = ConvertStringToColor(colorConverter, settingLocal.ColorSelfStr) + ?? Color.FromKnownColor(KnownColor.AliceBlue); + + this.ColorAtSelf = ConvertStringToColor(colorConverter, settingLocal.ColorAtSelfStr) + ?? Color.FromKnownColor(KnownColor.AntiqueWhite); + + this.ColorTarget = ConvertStringToColor(colorConverter, settingLocal.ColorTargetStr) + ?? Color.FromKnownColor(KnownColor.LemonChiffon); + + this.ColorAtTarget = ConvertStringToColor(colorConverter, settingLocal.ColorAtTargetStr) + ?? Color.FromKnownColor(KnownColor.LavenderBlush); + + this.ColorAtFromTarget = ConvertStringToColor(colorConverter, settingLocal.ColorAtFromTargetStr) + ?? Color.FromKnownColor(KnownColor.Honeydew); + + this.ColorAtTo = ConvertStringToColor(colorConverter, settingLocal.ColorAtToStr) + ?? Color.FromKnownColor(KnownColor.Pink); + + this.ColorListBackcolor = ConvertStringToColor(colorConverter, settingLocal.ColorListBackcolorStr) + ?? Color.FromKnownColor(KnownColor.Window); + + this.ColorInputBackcolor = ConvertStringToColor(colorConverter, settingLocal.ColorInputBackcolorStr) + ?? Color.FromKnownColor(KnownColor.LemonChiffon); + + this.ColorInputFont = ConvertStringToColor(colorConverter, settingLocal.ColorInputFontStr) + ?? Color.FromKnownColor(KnownColor.ControlText); this.BrushSelf = new SolidBrush(this.ColorSelf); this.BrushAtSelf = new SolidBrush(this.ColorAtSelf); @@ -170,9 +215,59 @@ public void Dispose() this.IsDisposed = true; } + public static Font? ConvertStringToFont(FontConverter converter, string? fontStr) + { + if (MyCommon.IsNullOrEmpty(fontStr)) + return null; + + try + { + return (Font)converter.ConvertFromString(fontStr); + } + catch + { + return null; + } + } + + public static string? ConvertFontToString(FontConverter converter, Font font, Font defaultValue) + { + static bool Equals(Font font1, Font font2) + => font1.Name == font2.Name && font1.Size == font2.Size && font1.Unit == font2.Unit && font1.Style == font2.Style; + + if (Equals(font, defaultValue)) + return null; + + return converter.ConvertToString(font); + } + + public static Color? ConvertStringToColor(ColorConverter converter, string? colorStr) + { + if (MyCommon.IsNullOrEmpty(colorStr)) + return null; + + try + { + return (Color)converter.ConvertFromString(colorStr); + } + catch + { + return null; + } + } + + public static string? ConvertColorToString(ColorConverter converter, Color color, Color defaultValue) + { + if (color == defaultValue) + return null; + + return converter.ConvertToString(color); + } + public static void ApplyGlobalUIFont(SettingLocal settingLocal) { - var font = settingLocal.FontUIGlobal; + var fontConverter = new FontConverter(); + var font = ConvertStringToFont(fontConverter, settingLocal.FontUIGlobalStr); if (font != null) OTBaseForm.GlobalFont = font; } From 125ca2e67e720c0fbd08956477d51adf5167ca71 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 9 Apr 2022 23:38:34 +0900 Subject: [PATCH 167/402] =?UTF-8?q?AppendSettingDialog=E3=81=8B=E3=82=89Tw?= =?UTF-8?q?itter=E3=82=A4=E3=83=B3=E3=82=B9=E3=82=BF=E3=83=B3=E3=82=B9?= =?UTF-8?q?=E3=81=AE=E4=BE=9D=E5=AD=98=E3=82=92=E9=99=A4=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/AppendSettingDialog.cs | 20 -------------------- OpenTween/Setting/Panel/BasedPanel.cs | 27 ++++++++++++++++++++++++++- OpenTween/Tween.cs | 17 +++++++---------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/OpenTween/AppendSettingDialog.cs b/OpenTween/AppendSettingDialog.cs index 574ed8f13..1c644813e 100644 --- a/OpenTween/AppendSettingDialog.cs +++ b/OpenTween/AppendSettingDialog.cs @@ -49,8 +49,6 @@ public partial class AppendSettingDialog : OTBaseForm { public event EventHandler? IntervalChanged; - internal Twitter Tw = null!; - public AppendSettingDialog() { this.InitializeComponent(); @@ -80,12 +78,6 @@ public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal) this.CooperatePanel.LoadConfig(settingCommon); this.ConnectionPanel.LoadConfig(settingCommon); this.NotifyPanel.LoadConfig(settingCommon); - - var activeUser = settingCommon.UserAccounts.FirstOrDefault(x => x.UserId == this.Tw.UserId); - if (activeUser != null) - { - this.BasedPanel.AuthUserCombo.SelectedItem = activeUser; - } } public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal) @@ -105,18 +97,6 @@ public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal) this.CooperatePanel.SaveConfig(settingCommon); this.ConnectionPanel.SaveConfig(settingCommon); this.NotifyPanel.SaveConfig(settingCommon); - - var userAccountIdx = this.BasedPanel.AuthUserCombo.SelectedIndex; - if (userAccountIdx != -1) - { - var u = settingCommon.UserAccounts[userAccountIdx]; - this.Tw.Initialize(u.Token, u.TokenSecret, u.Username, u.UserId); - } - else - { - this.Tw.ClearAuthInfo(); - this.Tw.Initialize("", "", "", 0); - } } private void TreeViewSetting_BeforeSelect(object sender, TreeViewCancelEventArgs e) diff --git a/OpenTween/Setting/Panel/BasedPanel.cs b/OpenTween/Setting/Panel/BasedPanel.cs index 6bb94a924..95911f992 100644 --- a/OpenTween/Setting/Panel/BasedPanel.cs +++ b/OpenTween/Setting/Panel/BasedPanel.cs @@ -48,11 +48,36 @@ public void LoadConfig(SettingCommon settingCommon) { this.AuthUserCombo.Items.Clear(); this.AuthUserCombo.Items.AddRange(settingCommon.UserAccounts.ToArray()); + + var selectedUserId = settingCommon.UserId; + var selectedAccount = settingCommon.UserAccounts.FirstOrDefault(x => x.UserId == selectedUserId); + if (selectedAccount != null) + this.AuthUserCombo.SelectedItem = selectedAccount; } } public void SaveConfig(SettingCommon settingCommon) - => settingCommon.UserAccounts = this.AuthUserCombo.Items.Cast().ToList(); + { + var accounts = this.AuthUserCombo.Items.Cast().ToList(); + settingCommon.UserAccounts = accounts; + + var selectedIndex = this.AuthUserCombo.SelectedIndex; + if (selectedIndex != -1) + { + var selectedAccount = accounts[selectedIndex]; + settingCommon.UserId = selectedAccount.UserId; + settingCommon.UserName = selectedAccount.Username; + settingCommon.Token = selectedAccount.Token; + settingCommon.TokenSecret = selectedAccount.TokenSecret; + } + else + { + settingCommon.UserId = 0; + settingCommon.UserName = ""; + settingCommon.Token = ""; + settingCommon.TokenSecret = ""; + } + } private void AuthClearButton_Click(object sender, EventArgs e) { diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 9466c56d1..3710430bf 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -3094,8 +3094,6 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) settingDialog.ShowInTaskbar = showTaskbarIcon; settingDialog.IntervalChanged += this.TimerInterval_Changed; - settingDialog.Tw = this.tw; - settingDialog.LoadConfig(this.settings.Common, this.settings.Local); try @@ -3121,8 +3119,7 @@ private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) private async void SettingStripMenuItem_Click(object sender, EventArgs e) { // 設定画面表示前のユーザー情報 - var oldUser = new { this.tw.AccessToken, this.tw.AccessTokenSecret, this.tw.Username, this.tw.UserId }; - + var previousUserId = this.settings.Common.UserId; var oldIconSz = this.settings.Common.IconSize; if (this.ShowSettingDialog() == DialogResult.OK) @@ -3130,6 +3127,11 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) lock (this.syncObject) { this.settings.ApplySettings(); + + if (MyCommon.IsNullOrEmpty(this.settings.Common.Token)) + this.tw.ClearAuthInfo(); + + this.tw.Initialize(this.settings.Common.Token, this.settings.Common.TokenSecret, this.settings.Common.UserName, this.settings.Common.UserId); this.tw.RestrictFavCheck = this.settings.Common.RestrictFavCheck; this.tw.ReadOwnPost = this.settings.Common.ReadOwnPost; @@ -3312,18 +3314,13 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) } } } - else - { - // キャンセル時は Twitter クラスの認証情報を画面表示前の状態に戻す - this.tw.Initialize(oldUser.AccessToken, oldUser.AccessTokenSecret, oldUser.Username, oldUser.UserId); - } Twitter.AccountState = MyCommon.ACCOUNT_STATE.Valid; this.TopMost = this.settings.Common.AlwaysTop; this.SaveConfigsAll(false); - if (this.tw.UserId != oldUser.UserId) + if (this.tw.UserId != previousUserId) await this.DoGetFollowersMenu(); } From 07718726278cd5077ed535dedd38438c7633a739 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 10 Apr 2022 16:48:37 +0900 Subject: [PATCH 168/402] =?UTF-8?q?=E5=88=9D=E5=9B=9E=E8=B5=B7=E5=8B=95?= =?UTF-8?q?=E6=99=82=E3=81=AE=E8=A8=AD=E5=AE=9A=E7=94=BB=E9=9D=A2=E3=81=AE?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E5=87=A6=E7=90=86=E3=82=92ApplicationEvents?= =?UTF-8?q?=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationEvents.cs | 27 +++++++++++++++++++++++++++ OpenTween/Setting/SettingManager.cs | 8 ++++++++ OpenTween/Tween.cs | 27 +++------------------------ 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index a25638c53..22b7eed42 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -88,6 +88,13 @@ public static int Main(string[] args) return 1; } + if (settings.IsIncomplete) + { + var completed = ShowSettingsDialog(settings, container.IconAssetsManager); + if (!completed) + return 1; // 設定が完了しなかったため終了 + } + Application.Run(container.MainForm); return 0; @@ -198,5 +205,25 @@ private static bool SetConfigDirectoryPath() return true; } + + private static bool ShowSettingsDialog(SettingManager settings, IconAssetsManager iconAssets) + { + using var settingDialog = new AppendSettingDialog(); + settingDialog.Icon = iconAssets.IconMain; + settingDialog.ShowInTaskbar = true; // この時点では TweenMain が表示されていないため代わりに表示する + settingDialog.LoadConfig(settings.Common, settings.Local); + + var ret = settingDialog.ShowDialog(); + if (ret != DialogResult.OK) + return false; + + settingDialog.SaveConfig(settings.Common, settings.Local); + + if (settings.IsIncomplete) + return false; + + settings.SaveAll(); + return true; + } } } diff --git a/OpenTween/Setting/SettingManager.cs b/OpenTween/Setting/SettingManager.cs index 30c97dd0a..6041f1f22 100644 --- a/OpenTween/Setting/SettingManager.cs +++ b/OpenTween/Setting/SettingManager.cs @@ -43,12 +43,20 @@ public class SettingManager public SettingAtIdList AtIdList { get; internal set; } = new(); + /// ユーザによる設定が必要な項目が残っているか + public bool IsIncomplete + => MyCommon.IsNullOrEmpty(this.Common.UserName); + + public bool IsFirstRun { get; private set; } = false; + public void LoadAll() { this.LoadCommon(); this.LoadLocal(); this.LoadTabs(); this.LoadAtIdList(); + + this.IsFirstRun = this.IsIncomplete; } public void LoadCommon() diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 3710430bf..ffe0dda05 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -599,23 +599,6 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter this.initial = true; - var saveRequired = false; - var firstRun = false; - - // ユーザー名、パスワードが未設定なら設定画面を表示(初回起動時など) - if (MyCommon.IsNullOrEmpty(this.tw.Username)) - { - saveRequired = true; - firstRun = true; - - // 設定せずにキャンセルされたか、設定されたが依然ユーザー名が未設定ならプログラム終了 - if (this.ShowSettingDialog(showTaskbarIcon: true) != DialogResult.OK || - MyCommon.IsNullOrEmpty(this.tw.Username)) - { - Application.Exit(); // 強制終了 - } - } - this.tw.RestrictFavCheck = this.settings.Common.RestrictFavCheck; this.tw.ReadOwnPost = this.settings.Common.ReadOwnPost; @@ -868,9 +851,8 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter this.ignoreConfigSave = false; this.TweenMain_Resize(this, EventArgs.Empty); - if (saveRequired) this.SaveConfigsAll(false); - if (firstRun) + if (this.settings.IsFirstRun) { // 初回起動時だけ右下のメニューを目立たせる this.HashStripSplitButton.ShowDropDown(); @@ -3084,18 +3066,15 @@ private async Task DoRefresh() private async Task DoRefreshMore() => await this.RefreshTabAsync(this.CurrentTab, backward: true); - private DialogResult ShowSettingDialog(bool showTaskbarIcon = false) + private DialogResult ShowSettingDialog() { - var result = DialogResult.Abort; - using var settingDialog = new AppendSettingDialog(); settingDialog.Icon = this.iconAssets.IconMain; - settingDialog.Owner = this; - settingDialog.ShowInTaskbar = showTaskbarIcon; settingDialog.IntervalChanged += this.TimerInterval_Changed; settingDialog.LoadConfig(this.settings.Common, this.settings.Local); + DialogResult result; try { result = settingDialog.ShowDialog(this); From 44d9b89af3845f4aa59d0ff72c0bb2a43d0507c0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 12 Apr 2022 00:15:33 +0900 Subject: [PATCH 169/402] =?UTF-8?q?SettingTabs=E3=81=8B=E3=82=89=E3=82=BF?= =?UTF-8?q?=E3=83=96=E3=81=AE=E8=A8=AD=E5=AE=9A=E3=82=92=E5=BE=A9=E5=85=83?= =?UTF-8?q?=E3=81=99=E3=82=8B=E5=87=A6=E7=90=86=E3=82=92TabInformations?= =?UTF-8?q?=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/TabInformationTest.cs | 61 +++++++++++++++++++ OpenTween/Models/TabInformations.cs | 63 ++++++++++++++++++++ OpenTween/Tween.cs | 60 +------------------ 3 files changed, 125 insertions(+), 59 deletions(-) diff --git a/OpenTween.Tests/Models/TabInformationTest.cs b/OpenTween.Tests/Models/TabInformationTest.cs index ae4dff643..4545169f6 100644 --- a/OpenTween.Tests/Models/TabInformationTest.cs +++ b/OpenTween.Tests/Models/TabInformationTest.cs @@ -108,6 +108,67 @@ public void SelectTab_Test() public void SelectTab_NotExistTest() => Assert.Throws(() => this.tabinfo.SelectTab("INVALID")); + [Theory] + [InlineData(MyCommon.TabUsageType.Home, typeof(HomeTabModel))] + [InlineData(MyCommon.TabUsageType.Mentions, typeof(MentionsTabModel))] + [InlineData(MyCommon.TabUsageType.DirectMessage, typeof(DirectMessagesTabModel))] + [InlineData(MyCommon.TabUsageType.Favorites, typeof(FavoritesTabModel))] + [InlineData(MyCommon.TabUsageType.UserDefined, typeof(FilterTabModel))] + [InlineData(MyCommon.TabUsageType.UserTimeline, typeof(UserTimelineTabModel))] + [InlineData(MyCommon.TabUsageType.PublicSearch, typeof(PublicSearchTabModel))] + [InlineData(MyCommon.TabUsageType.Lists, typeof(ListTimelineTabModel))] + [InlineData(MyCommon.TabUsageType.Mute, typeof(MuteTabModel))] + public void CreateTabFromSettings_TabTypeTest(MyCommon.TabUsageType tabType, Type expected) + { + var tabSetting = new SettingTabs.SettingTabItem + { + TabName = "tab", + TabType = tabType, + }; + var tabinfo = this.CreateInstance(); + var tab = tabinfo.CreateTabFromSettings(tabSetting); + Assert.IsType(expected, tab); + } + + [Fact] + public void CreateTabFromSettings_FilterTabTest() + { + var tabSetting = new SettingTabs.SettingTabItem + { + TabName = "tab", + TabType = MyCommon.TabUsageType.UserDefined, + FilterArray = new PostFilterRule[] + { + new() { FilterName = "foo" }, + }, + }; + var tabinfo = this.CreateInstance(); + var tab = tabinfo.CreateTabFromSettings(tabSetting); + Assert.IsType(tab); + + var filterTab = (FilterTabModel)tab!; + Assert.Equal("foo", filterTab.FilterArray.First().FilterName); + } + + [Fact] + public void CreateTabFromSettings_PublicSearchTabTest() + { + var tabSetting = new SettingTabs.SettingTabItem + { + TabName = "tab", + TabType = MyCommon.TabUsageType.PublicSearch, + SearchWords = "foo", + SearchLang = "ja", + }; + var tabinfo = this.CreateInstance(); + var tab = tabinfo.CreateTabFromSettings(tabSetting); + Assert.IsType(tab); + + var searchTab = (PublicSearchTabModel)tab!; + Assert.Equal("foo", searchTab.SearchWords); + Assert.Equal("ja", searchTab.SearchLang); + } + [Fact] public void AddDefaultTabs_Test() { diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index a35dc4e90..a9769d3d5 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -209,6 +209,69 @@ public void SelectTab(string tabName) this.SelectedTabName = tabName; } + public void LoadTabsFromSettings(SettingTabs settingTabs) + { + foreach (var tabSetting in settingTabs.Tabs) + { + var tab = this.CreateTabFromSettings(tabSetting); + if (tab == null) + continue; + + if (this.ContainsTab(tab.TabName)) + tab.TabName = this.MakeTabName("MyTab"); + + this.AddTab(tab); + } + } + + public TabModel? CreateTabFromSettings(SettingTabs.SettingTabItem tabSetting) + { + var tabName = tabSetting.TabName; + + TabModel? tab = tabSetting.TabType switch + { + MyCommon.TabUsageType.Home + => new HomeTabModel(tabName), + MyCommon.TabUsageType.Mentions + => new MentionsTabModel(tabName), + MyCommon.TabUsageType.DirectMessage + => new DirectMessagesTabModel(tabName), + MyCommon.TabUsageType.Favorites + => new FavoritesTabModel(tabName), + MyCommon.TabUsageType.UserDefined + => new FilterTabModel(tabName), + MyCommon.TabUsageType.UserTimeline + => new UserTimelineTabModel(tabName, tabSetting.User!), + MyCommon.TabUsageType.PublicSearch + => new PublicSearchTabModel(tabName) + { + SearchWords = tabSetting.SearchWords, + SearchLang = tabSetting.SearchLang, + }, + MyCommon.TabUsageType.Lists + => new ListTimelineTabModel(tabName, tabSetting.ListInfo!), + MyCommon.TabUsageType.Mute + => new MuteTabModel(tabName), + _ => null, + }; + + if (tab == null) + return null; + + tab.UnreadManage = tabSetting.UnreadManage; + tab.Protected = tabSetting.Protected; + tab.Notify = tabSetting.Notify; + tab.SoundFile = tabSetting.SoundFile; + + if (tab is FilterTabModel filterTab) + { + filterTab.FilterArray = tabSetting.FilterArray; + filterTab.FilterModified = false; + } + + return tab; + } + /// /// デフォルトのタブを追加する /// diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index ffe0dda05..4b031a7ac 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -913,65 +913,7 @@ private void LoadConfig() if (this.settings.Local.ScaleDimension.IsEmpty) this.settings.Local.ScaleDimension = this.CurrentAutoScaleDimensions; - var tabSettings = this.settings.Tabs; - foreach (var tabSetting in tabSettings.Tabs) - { - TabModel tab; - switch (tabSetting.TabType) - { - case MyCommon.TabUsageType.Home: - tab = new HomeTabModel(tabSetting.TabName); - break; - case MyCommon.TabUsageType.Mentions: - tab = new MentionsTabModel(tabSetting.TabName); - break; - case MyCommon.TabUsageType.DirectMessage: - tab = new DirectMessagesTabModel(tabSetting.TabName); - break; - case MyCommon.TabUsageType.Favorites: - tab = new FavoritesTabModel(tabSetting.TabName); - break; - case MyCommon.TabUsageType.UserDefined: - tab = new FilterTabModel(tabSetting.TabName); - break; - case MyCommon.TabUsageType.UserTimeline: - tab = new UserTimelineTabModel(tabSetting.TabName, tabSetting.User!); - break; - case MyCommon.TabUsageType.PublicSearch: - tab = new PublicSearchTabModel(tabSetting.TabName) - { - SearchWords = tabSetting.SearchWords, - SearchLang = tabSetting.SearchLang, - }; - break; - case MyCommon.TabUsageType.Lists: - tab = new ListTimelineTabModel(tabSetting.TabName, tabSetting.ListInfo!); - break; - case MyCommon.TabUsageType.Mute: - tab = new MuteTabModel(tabSetting.TabName); - break; - default: - continue; - } - - tab.UnreadManage = tabSetting.UnreadManage; - tab.Protected = tabSetting.Protected; - tab.Notify = tabSetting.Notify; - tab.SoundFile = tabSetting.SoundFile; - - if (tab.IsDistributableTabType) - { - var filterTab = (FilterTabModel)tab; - filterTab.FilterArray = tabSetting.FilterArray; - filterTab.FilterModified = false; - } - - if (this.statuses.ContainsTab(tab.TabName)) - tab.TabName = this.statuses.MakeTabName("MyTab"); - - this.statuses.AddTab(tab); - } - + this.statuses.LoadTabsFromSettings(this.settings.Tabs); this.statuses.AddDefaultTabs(); } From 2540971d939b1f6627253a6a3ab8c4753ce029ed Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 12 Apr 2022 23:38:20 +0900 Subject: [PATCH 170/402] =?UTF-8?q?ThumbnailGenerator=E3=82=92ApplicationC?= =?UTF-8?q?ontainer=E5=86=85=E3=81=A7=E5=88=9D=E6=9C=9F=E5=8C=96=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TweetThumbnailTest.cs | 22 +++++++++++++------- OpenTween/ApplicationContainer.cs | 21 ++++++++++++++++++- OpenTween/Thumbnail/ThumbnailGenerator.cs | 25 ++++++++++------------- OpenTween/Tween.cs | 21 ++++++++++++++----- OpenTween/TweetThumbnail.cs | 12 ++++++++++- 5 files changed, 73 insertions(+), 28 deletions(-) diff --git a/OpenTween.Tests/TweetThumbnailTest.cs b/OpenTween.Tests/TweetThumbnailTest.cs index 183cfc51f..9f274ec8b 100644 --- a/OpenTween.Tests/TweetThumbnailTest.cs +++ b/OpenTween.Tests/TweetThumbnailTest.cs @@ -79,20 +79,21 @@ public override Task LoadThumbnailImageAsync(HttpClient http, Cance } public TweetThumbnailTest() - { - this.ThumbnailGeneratorSetup(); - this.MyCommonSetup(); - } + => this.MyCommonSetup(); - private void ThumbnailGeneratorSetup() + private ThumbnailGenerator CreateThumbnailGenerator() { - ThumbnailGenerator.Services.Clear(); - ThumbnailGenerator.Services.AddRange(new[] + var imgAzyobuziNet = new ImgAzyobuziNet(autoupdate: false); + var thumbGenerator = new ThumbnailGenerator(imgAzyobuziNet); + thumbGenerator.Services.Clear(); + thumbGenerator.Services.AddRange(new[] { new TestThumbnailService(@"^https?://foo.example.com/(.+)$", @"http://img.example.com/${1}.png", null), new TestThumbnailService(@"^https?://bar.example.com/(.+)$", @"http://img.example.com/${1}.png", @"${1}"), new TestThumbnailService(@"^https?://slow.example.com/(.+)$", @"http://img.example.com/${1}.png", null), }); + + return thumbGenerator; } private void MyCommonSetup() @@ -133,6 +134,8 @@ public async Task CancelAsyncTest() }; using var thumbbox = new TweetThumbnail(); + thumbbox.Initialize(this.CreateThumbnailGenerator()); + using var tokenSource = new CancellationTokenSource(); SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); @@ -151,6 +154,7 @@ public async Task CancelAsyncTest() public void SetThumbnailCountTest(int count) { using var thumbbox = new TweetThumbnail(); + thumbbox.Initialize(this.CreateThumbnailGenerator()); var method = typeof(TweetThumbnail).GetMethod("SetThumbnailCount", BindingFlags.Instance | BindingFlags.NonPublic); method.Invoke(thumbbox, new[] { (object)count }); @@ -187,6 +191,7 @@ public async Task ShowThumbnailAsyncTest() }; using var thumbbox = new TweetThumbnail(); + thumbbox.Initialize(this.CreateThumbnailGenerator()); SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); @@ -220,6 +225,7 @@ public async Task ShowThumbnailAsyncTest2() }; using var thumbbox = new TweetThumbnail(); + thumbbox.Initialize(this.CreateThumbnailGenerator()); SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); @@ -251,6 +257,7 @@ public async Task ShowThumbnailAsyncTest2() public async Task ThumbnailLoadingEventTest() { using var thumbbox = new TweetThumbnail(); + thumbbox.Initialize(this.CreateThumbnailGenerator()); SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); @@ -299,6 +306,7 @@ public async Task ScrollTest() }; using var thumbbox = new TweetThumbnail(); + thumbbox.Initialize(this.CreateThumbnailGenerator()); SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); diff --git a/OpenTween/ApplicationContainer.cs b/OpenTween/ApplicationContainer.cs index 5d63d7371..c9e8b607e 100644 --- a/OpenTween/ApplicationContainer.cs +++ b/OpenTween/ApplicationContainer.cs @@ -25,6 +25,8 @@ using OpenTween.Api; using OpenTween.Models; using OpenTween.Setting; +using OpenTween.Thumbnail; +using OpenTween.Thumbnail.Services; namespace OpenTween { @@ -51,6 +53,12 @@ public ImageCache ImageCache public IconAssetsManager IconAssetsManager => this.iconAssetsManagerLazy.Value; + public ImgAzyobuziNet ImgAzyobuziNet + => this.imgAzyobuziNetLazy.Value; + + public ThumbnailGenerator ThumbnailGenerator + => this.thumbnailGeneratorLazy.Value; + public TweenMain MainForm => this.mainFormLazy.Value; @@ -59,6 +67,8 @@ public TweenMain MainForm private readonly DisposableLazy twitterLazy; private readonly DisposableLazy imageCacheLazy; private readonly DisposableLazy iconAssetsManagerLazy; + private readonly DisposableLazy imgAzyobuziNetLazy; + private readonly Lazy thumbnailGeneratorLazy; private readonly DisposableLazy mainFormLazy; public ApplicationContainer() @@ -68,6 +78,8 @@ public ApplicationContainer() this.twitterLazy = new(this.CreateTwitter); this.imageCacheLazy = new(this.CreateImageCache); this.iconAssetsManagerLazy = new(this.CreateIconAssetsManager); + this.imgAzyobuziNetLazy = new(this.CreateImgAzyobuziNet); + this.thumbnailGeneratorLazy = new(this.CreateThumbnailGenerator); this.mainFormLazy = new(this.CreateTweenMain); } @@ -86,8 +98,14 @@ private ImageCache CreateImageCache() private IconAssetsManager CreateIconAssetsManager() => new(); + private ImgAzyobuziNet CreateImgAzyobuziNet() + => new(autoupdate: false); + + private ThumbnailGenerator CreateThumbnailGenerator() + => new(this.ImgAzyobuziNet); + private TweenMain CreateTweenMain() - => new(this.Settings, this.TabInfo, this.Twitter, this.ImageCache, this.IconAssetsManager); + => new(this.Settings, this.TabInfo, this.Twitter, this.ImageCache, this.IconAssetsManager, this.ThumbnailGenerator); public void Dispose() { @@ -96,6 +114,7 @@ public void Dispose() this.IsDisposed = true; this.mainFormLazy.Dispose(); + this.imgAzyobuziNetLazy.Dispose(); this.twitterLazy.Dispose(); this.twitterApiLazy.Dispose(); this.iconAssetsManagerLazy.Dispose(); diff --git a/OpenTween/Thumbnail/ThumbnailGenerator.cs b/OpenTween/Thumbnail/ThumbnailGenerator.cs index 39c6dbaac..033eb35b5 100644 --- a/OpenTween/Thumbnail/ThumbnailGenerator.cs +++ b/OpenTween/Thumbnail/ThumbnailGenerator.cs @@ -34,25 +34,22 @@ namespace OpenTween.Thumbnail { - public class ThumbnailGenerator + public sealed class ThumbnailGenerator { public static readonly Regex InstagramPattern = new( @"^https?://(?:instagram.com|instagr\.am|i\.instagram\.com|www\.instagram\.com)/([^/]+/)?p/(?[^/]+)/(\?.*)?$", RegexOptions.IgnoreCase ); - public static List Services { get; protected set; } + public List Services { get; } - internal static ImgAzyobuziNet ImgAzyobuziNetInstance { get; private set; } = null!; + public ImgAzyobuziNet ImgAzyobuziNet { get; } - static ThumbnailGenerator() - => ThumbnailGenerator.Services = new List(); - - public static void InitializeGenerator() + public ThumbnailGenerator(ImgAzyobuziNet imgAzyobuziNet) { - ImgAzyobuziNetInstance = new ImgAzyobuziNet(autoupdate: true); + this.ImgAzyobuziNet = imgAzyobuziNet; - ThumbnailGenerator.Services = new List + this.Services = new List { // ton.twitter.com new TonTwitterCom(), @@ -76,7 +73,7 @@ public static void InitializeGenerator() new SimpleThumbnailService(@"^https?://.*(\.jpg|\.jpeg|\.gif|\.png|\.bmp)$", "${0}"), // img.azyobuzi.net - ImgAzyobuziNetInstance, + this.ImgAzyobuziNet, // ImgUr new SimpleThumbnailService( @@ -161,7 +158,7 @@ public static void InitializeGenerator() }; } - public static async Task> GetThumbnailsAsync(PostClass post, CancellationToken token) + public async Task> GetThumbnailsAsync(PostClass post, CancellationToken token) { var thumbnails = new List(); @@ -170,7 +167,7 @@ public static async Task> GetThumbnailsAsync(PostClas foreach (var expandedUrl in expandedUrls) { - var thumbInfo = await ThumbnailGenerator.GetThumbnailInfoAsync(expandedUrl, post, token) + var thumbInfo = await this.GetThumbnailInfoAsync(expandedUrl, post, token) .ConfigureAwait(false); if (thumbInfo != null) @@ -190,9 +187,9 @@ public static async Task> GetThumbnailsAsync(PostClas return thumbnails; } - public static async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) + public async Task GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token) { - foreach (var generator in ThumbnailGenerator.Services) + foreach (var generator in this.Services) { var result = await generator.GetThumbnailInfoAsync(url, post, token) .ConfigureAwait(false); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 4b031a7ac..d0572a679 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -164,6 +164,8 @@ public partial class TweenMain : OTBaseForm private readonly IconAssetsManager iconAssets; + private readonly ThumbnailGenerator thumbGenerator; + private readonly ImageList listViewImageList = new(); // ListViewItemの高さ変更用 private PostClass? anchorPost; @@ -540,13 +542,21 @@ private void InitColumnText() } } - public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter twitter, ImageCache imageCache, IconAssetsManager iconAssets) + public TweenMain( + SettingManager settingManager, + TabInformations tabInfo, + Twitter twitter, + ImageCache imageCache, + IconAssetsManager iconAssets, + ThumbnailGenerator thumbGenerator + ) { this.settings = settingManager; this.statuses = tabInfo; this.tw = twitter; this.iconCache = imageCache; this.iconAssets = iconAssets; + this.thumbGenerator = thumbGenerator; this.InitializeComponent(); @@ -620,17 +630,18 @@ public TweenMain(SettingManager settingManager, TabInformations tabInfo, Twitter // サムネイル関連の初期化 // プロキシ設定等の通信まわりの初期化が済んでから処理する - ThumbnailGenerator.InitializeGenerator(); - - var imgazyobizinet = ThumbnailGenerator.ImgAzyobuziNetInstance; + var imgazyobizinet = this.thumbGenerator.ImgAzyobuziNet; imgazyobizinet.Enabled = this.settings.Common.EnableImgAzyobuziNet; imgazyobizinet.DisabledInDM = this.settings.Common.ImgAzyobuziNetDisabledInDM; + imgazyobizinet.AutoUpdate = true; Thumbnail.Services.TonTwitterCom.GetApiConnection = () => this.tw.Api.Connection; // 画像投稿サービス this.ImageSelector.Initialize(this.tw, this.tw.Configuration, this.settings.Common.UseImageServiceName, this.settings.Common.UseImageService); + this.tweetThumbnail1.Initialize(this.thumbGenerator); + // ハッシュタグ/@id関連 this.AtIdSupl = new AtIdSupplement(this.settings.AtIdList.AtIdList, "@"); this.HashSupl = new AtIdSupplement(this.settings.Common.HashTags, "#"); @@ -3113,7 +3124,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) this.SplitContainer1.IsPanelInverted = !this.settings.Common.StatusAreaAtBottom; - var imgazyobizinet = ThumbnailGenerator.ImgAzyobuziNetInstance; + var imgazyobizinet = this.thumbGenerator.ImgAzyobuziNet; imgazyobizinet.Enabled = this.settings.Common.EnableImgAzyobuziNet; imgazyobizinet.DisabledInDM = this.settings.Common.ImgAzyobuziNetDisabledInDM; diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index 1fa4d49a9..dddb955cb 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -45,6 +45,7 @@ public partial class TweetThumbnail : UserControl { protected internal List PictureBox = new(); protected MouseWheelMessageFilter filter = new(); + private ThumbnailGenerator? thumbGenerator; public event EventHandler? ThumbnailLoading; @@ -55,9 +56,18 @@ public partial class TweetThumbnail : UserControl public ThumbnailInfo Thumbnail => (ThumbnailInfo)this.PictureBox[this.scrollBar.Value].Tag; + private ThumbnailGenerator ThumbGenerator + => this.thumbGenerator ?? throw this.NotInitializedException(); + public TweetThumbnail() => this.InitializeComponent(); + public void Initialize(ThumbnailGenerator thumbnailGenerator) + => this.thumbGenerator = thumbnailGenerator; + + private Exception NotInitializedException() + => new InvalidOperationException("Cannot call before initialization"); + public Task ShowThumbnailAsync(PostClass post) => this.ShowThumbnailAsync(post, CancellationToken.None); @@ -122,7 +132,7 @@ private string GetImageSearchUriSauceNao(string imageUri) => @"https://saucenao.com/search.php?url=" + Uri.EscapeDataString(imageUri); protected virtual Task> GetThumbailInfoAsync(PostClass post, CancellationToken token) - => ThumbnailGenerator.GetThumbnailsAsync(post, token); + => this.ThumbGenerator.GetThumbnailsAsync(post, token); /// /// 表示するサムネイルの数を設定する From 7210784606ad3a41a223652536809f6effb6041b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 15 Apr 2022 23:05:25 +0900 Subject: [PATCH 171/402] =?UTF-8?q?SettingLocal=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AE=20Width*=20=E3=81=8A=E3=82=88=E3=81=B3=20DisplayIndex?= =?UTF-8?q?*=20=E3=82=92=20ColumnsWidth/ColumnsOrder=20=E3=81=AB=E7=A7=BB?= =?UTF-8?q?=E8=A1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Setting/SettingLocal.cs | 119 +++++++++++++++++++++---- OpenTween/Tween.cs | 143 ++++++------------------------ 2 files changed, 132 insertions(+), 130 deletions(-) diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index 001a808e8..2e3636537 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -61,22 +61,109 @@ public void Save() public string StatusText = ""; public bool UseRecommendStatus = false; - public int Width1 = 48; - public int Width2 = 80; - public int Width3 = 290; - public int Width4 = 120; - public int Width5 = 50; - public int Width6 = 16; - public int Width7 = 32; - public int Width8 = 50; - public int DisplayIndex1 = 2; - public int DisplayIndex2 = 3; - public int DisplayIndex3 = 4; - public int DisplayIndex4 = 5; - public int DisplayIndex5 = 6; - public int DisplayIndex6 = 1; - public int DisplayIndex7 = 0; - public int DisplayIndex8 = 7; + + [XmlIgnore] + public int[] ColumnsWidth { get; } = { 48, 80, 290, 120, 50, 16, 32, 50 }; + + public int Width1 + { + get => this.ColumnsWidth[0]; + set => this.ColumnsWidth[0] = value; + } + + public int Width2 + { + get => this.ColumnsWidth[1]; + set => this.ColumnsWidth[1] = value; + } + + public int Width3 + { + get => this.ColumnsWidth[2]; + set => this.ColumnsWidth[2] = value; + } + + public int Width4 + { + get => this.ColumnsWidth[3]; + set => this.ColumnsWidth[3] = value; + } + + public int Width5 + { + get => this.ColumnsWidth[4]; + set => this.ColumnsWidth[4] = value; + } + + public int Width6 + { + get => this.ColumnsWidth[5]; + set => this.ColumnsWidth[5] = value; + } + + public int Width7 + { + get => this.ColumnsWidth[6]; + set => this.ColumnsWidth[6] = value; + } + + public int Width8 + { + get => this.ColumnsWidth[7]; + set => this.ColumnsWidth[7] = value; + } + + [XmlIgnore] + public int[] ColumnsOrder { get; } = { 2, 3, 4, 5, 6, 1, 0, 7 }; + + public int DisplayIndex1 + { + get => this.ColumnsOrder[0]; + set => this.ColumnsOrder[0] = value; + } + + public int DisplayIndex2 + { + get => this.ColumnsOrder[1]; + set => this.ColumnsOrder[1] = value; + } + + public int DisplayIndex3 + { + get => this.ColumnsOrder[2]; + set => this.ColumnsOrder[2] = value; + } + + public int DisplayIndex4 + { + get => this.ColumnsOrder[3]; + set => this.ColumnsOrder[3] = value; + } + + public int DisplayIndex5 + { + get => this.ColumnsOrder[4]; + set => this.ColumnsOrder[4] = value; + } + + public int DisplayIndex6 + { + get => this.ColumnsOrder[5]; + set => this.ColumnsOrder[5] = value; + } + + public int DisplayIndex7 + { + get => this.ColumnsOrder[6]; + set => this.ColumnsOrder[6] = value; + } + + public int DisplayIndex8 + { + get => this.ColumnsOrder[7]; + set => this.ColumnsOrder[7] = value; + } + public string BrowserPath = ""; public ProxyType ProxyType = ProxyType.IE; public string ProxyAddress = "127.0.0.1"; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index d0572a679..d8c0b92b1 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -399,8 +399,8 @@ private void InitColumns(ListView list, bool startup) { var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / this.settings.Local.ScaleDimension.Width; - columns[0].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width1); - columns[1].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width3); + columns[0].Width = ScaleBy(widthScaleFactor, this.settings.Local.ColumnsWidth[0]); + columns[1].Width = ScaleBy(widthScaleFactor, this.settings.Local.ColumnsWidth[2]); columns[0].DisplayIndex = 0; columns[1].DisplayIndex = 1; } @@ -436,26 +436,10 @@ private void InitColumns(ListView list, bool startup) { var widthScaleFactor = this.CurrentAutoScaleDimensions.Width / this.settings.Local.ScaleDimension.Width; - columns[0].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width1); - columns[1].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width2); - columns[2].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width3); - columns[3].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width4); - columns[4].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width5); - columns[5].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width6); - columns[6].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width7); - columns[7].Width = ScaleBy(widthScaleFactor, this.settings.Local.Width8); - - var displayIndex = new[] - { - this.settings.Local.DisplayIndex1, this.settings.Local.DisplayIndex2, - this.settings.Local.DisplayIndex3, this.settings.Local.DisplayIndex4, - this.settings.Local.DisplayIndex5, this.settings.Local.DisplayIndex6, - this.settings.Local.DisplayIndex7, this.settings.Local.DisplayIndex8, - }; - - foreach (var i in Enumerable.Range(0, displayIndex.Length)) + foreach (var (column, index) in columns.WithIndex()) { - columns[i].DisplayIndex = displayIndex[i]; + column.Width = ScaleBy(widthScaleFactor, this.settings.Local.ColumnsWidth[index]); + column.DisplayIndex = this.settings.Local.ColumnsOrder[index]; } } else @@ -8483,62 +8467,24 @@ private void MenuStrip1_MenuDeactivate(object sender, EventArgs e) private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e) { - var lst = (DetailsListView)sender; - if (this.settings.Local == null) return; - if (this.iconCol) { - this.settings.Local.Width1 = lst.Columns[0].Width; - this.settings.Local.Width3 = lst.Columns[1].Width; + e.Cancel = true; + return; } - else - { - var darr = new int[lst.Columns.Count]; - for (var i = 0; i < lst.Columns.Count; i++) - { - darr[lst.Columns[i].DisplayIndex] = i; - } - MyCommon.MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex); - for (var i = 0; i < lst.Columns.Count; i++) - { - switch (darr[i]) - { - case 0: - this.settings.Local.DisplayIndex1 = i; - break; - case 1: - this.settings.Local.DisplayIndex2 = i; - break; - case 2: - this.settings.Local.DisplayIndex3 = i; - break; - case 3: - this.settings.Local.DisplayIndex4 = i; - break; - case 4: - this.settings.Local.DisplayIndex5 = i; - break; - case 5: - this.settings.Local.DisplayIndex6 = i; - break; - case 6: - this.settings.Local.DisplayIndex7 = i; - break; - case 7: - this.settings.Local.DisplayIndex8 = i; - break; - } - } - this.settings.Local.Width1 = lst.Columns[0].Width; - this.settings.Local.Width2 = lst.Columns[1].Width; - this.settings.Local.Width3 = lst.Columns[2].Width; - this.settings.Local.Width4 = lst.Columns[3].Width; - this.settings.Local.Width5 = lst.Columns[4].Width; - this.settings.Local.Width6 = lst.Columns[5].Width; - this.settings.Local.Width7 = lst.Columns[6].Width; - this.settings.Local.Width8 = lst.Columns[7].Width; - } + var lst = (DetailsListView)sender; + var columnsCount = lst.Columns.Count; + + var darr = new int[columnsCount]; + for (var i = 0; i < columnsCount; i++) + darr[lst.Columns[i].DisplayIndex] = i; + + MyCommon.MoveArrayItem(darr, e.OldDisplayIndex, e.NewDisplayIndex); + + for (var i = 0; i < columnsCount; i++) + this.settings.Local.ColumnsOrder[darr[i]] = i; + this.MarkSettingLocalModified(); this.isColumnChanged = true; } @@ -8551,57 +8497,26 @@ private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArg var modified = false; if (this.iconCol) { - if (this.settings.Local.Width1 != lst.Columns[0].Width) + if (this.settings.Local.ColumnsWidth[0] != lst.Columns[0].Width) { - this.settings.Local.Width1 = lst.Columns[0].Width; + this.settings.Local.ColumnsWidth[0] = lst.Columns[0].Width; modified = true; } - if (this.settings.Local.Width3 != lst.Columns[1].Width) + if (this.settings.Local.ColumnsWidth[2] != lst.Columns[1].Width) { - this.settings.Local.Width3 = lst.Columns[1].Width; + this.settings.Local.ColumnsWidth[2] = lst.Columns[1].Width; modified = true; } } else { - if (this.settings.Local.Width1 != lst.Columns[0].Width) - { - this.settings.Local.Width1 = lst.Columns[0].Width; - modified = true; - } - if (this.settings.Local.Width2 != lst.Columns[1].Width) + var columnsCount = lst.Columns.Count; + for (var i = 0; i < columnsCount; i++) { - this.settings.Local.Width2 = lst.Columns[1].Width; - modified = true; - } - if (this.settings.Local.Width3 != lst.Columns[2].Width) - { - this.settings.Local.Width3 = lst.Columns[2].Width; - modified = true; - } - if (this.settings.Local.Width4 != lst.Columns[3].Width) - { - this.settings.Local.Width4 = lst.Columns[3].Width; - modified = true; - } - if (this.settings.Local.Width5 != lst.Columns[4].Width) - { - this.settings.Local.Width5 = lst.Columns[4].Width; - modified = true; - } - if (this.settings.Local.Width6 != lst.Columns[5].Width) - { - this.settings.Local.Width6 = lst.Columns[5].Width; - modified = true; - } - if (this.settings.Local.Width7 != lst.Columns[6].Width) - { - this.settings.Local.Width7 = lst.Columns[6].Width; - modified = true; - } - if (this.settings.Local.Width8 != lst.Columns[7].Width) - { - this.settings.Local.Width8 = lst.Columns[7].Width; + if (this.settings.Local.ColumnsWidth[i] == lst.Columns[i].Width) + continue; + + this.settings.Local.ColumnsWidth[i] = lst.Columns[i].Width; modified = true; } } From 9d052bc35fb8e6e5251a002325bc80732085d835 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 16 Apr 2022 04:08:11 +0900 Subject: [PATCH 172/402] =?UTF-8?q?MyCommon.SettingPath=E3=82=92=E5=BB=83?= =?UTF-8?q?=E6=AD=A2=E3=81=97SettingManager=E3=82=A4=E3=83=B3=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=83=B3=E3=82=B9=E5=86=85=E3=81=AESettingsPath?= =?UTF-8?q?=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ApplicationContainer.cs | 7 +- OpenTween/ApplicationEvents.cs | 100 ++-------------------- OpenTween/MyCommon.cs | 12 ++- OpenTween/Setting/SettingAtIdList.cs | 11 +-- OpenTween/Setting/SettingBase.cs | 26 +++--- OpenTween/Setting/SettingCommon.cs | 8 +- OpenTween/Setting/SettingLocal.cs | 8 +- OpenTween/Setting/SettingManager.cs | 120 +++++++++++++++++++++++++-- OpenTween/Setting/SettingTabs.cs | 8 +- OpenTween/Tween.cs | 4 +- 10 files changed, 158 insertions(+), 146 deletions(-) diff --git a/OpenTween/ApplicationContainer.cs b/OpenTween/ApplicationContainer.cs index c9e8b607e..9a101c25d 100644 --- a/OpenTween/ApplicationContainer.cs +++ b/OpenTween/ApplicationContainer.cs @@ -34,7 +34,7 @@ public sealed class ApplicationContainer : IDisposable { public bool IsDisposed { get; private set; } = false; - public SettingManager Settings { get; } = SettingManager.Instance; + public SettingManager Settings { get; } public TabInformations TabInfo { get; } = TabInformations.GetInstance(); @@ -71,8 +71,11 @@ public TweenMain MainForm private readonly Lazy thumbnailGeneratorLazy; private readonly DisposableLazy mainFormLazy; - public ApplicationContainer() + public ApplicationContainer(SettingManager settings) { + this.Settings = settings; + SettingManager.Instance = settings; + this.cultureServiceLazy = new(this.CreateCultureService); this.twitterApiLazy = new(this.CreateTwitterApi); this.twitterLazy = new(this.CreateTwitter); diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 22b7eed42..4946bcf9c 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -28,7 +28,6 @@ #nullable enable using System; -using System.IO; using System.Windows.Forms; using OpenTween.Connection; using OpenTween.Setting; @@ -59,14 +58,15 @@ public static int Main(string[] args) if (!ApplicationPreconditions.CheckAll()) return 1; - if (!SetConfigDirectoryPath()) + var settingsPath = SettingManager.DetermineSettingsPath(StartupOptions); + if (MyCommon.IsNullOrEmpty(settingsPath)) return 1; - using var container = new ApplicationContainer(); - - var settings = container.Settings; + var settings = new SettingManager(settingsPath); settings.LoadAll(); + using var container = new ApplicationContainer(settings); + var noLimit = StartupOptions.ContainsKey("nolimit"); settings.Common.Validate(noLimit); @@ -77,7 +77,7 @@ public static int Main(string[] args) settings.ApplySettings(); // 同じ設定ファイルを使用する OpenTween プロセスの二重起動を防止する - using var mutex = new ApplicationInstanceMutex(ApplicationSettings.AssemblyName, MyCommon.SettingPath); + using var mutex = new ApplicationInstanceMutex(ApplicationSettings.AssemblyName, settings.SettingsPath); if (mutex.InstanceExists) { @@ -118,94 +118,6 @@ private static void InitializeTraceFrag() MyCommon.TraceFlag = traceFlag; } - private static bool SetConfigDirectoryPath() - { - if (StartupOptions.TryGetValue("configDir", out var configDir) && !MyCommon.IsNullOrEmpty(configDir)) - { - // 起動オプション /configDir で設定ファイルの参照先を変更できます - if (!Directory.Exists(configDir)) - { - var text = string.Format(Properties.Resources.ConfigDirectoryNotExist, configDir); - MessageBox.Show(text, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error); - return false; - } - - MyCommon.SettingPath = Path.GetFullPath(configDir); - } - else - { - // OpenTween.exe と同じディレクトリに設定ファイルを配置する - MyCommon.SettingPath = Application.StartupPath; - - SettingManager.Instance.LoadAll(); - - try - { - // 設定ファイルが書き込み可能な状態であるかテストする - SettingManager.Instance.SaveAll(); - } - catch (UnauthorizedAccessException) - { - // 書き込みに失敗した場合 (Program Files 以下に配置されている場合など) - - // 通常は C:\Users\ユーザー名\AppData\Roaming\OpenTween\ となる - var roamingDir = Path.Combine(new[] - { - Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), - ApplicationSettings.ApplicationName, - }); - Directory.CreateDirectory(roamingDir); - - MyCommon.SettingPath = roamingDir; - - /* - * 書き込みが制限されたディレクトリ内で起動された場合の設定ファイルの扱い - * - * (A) StartupPath に存在する設定ファイル - * (B) Roaming に存在する設定ファイル - * - * 1. A も B も存在しない場合 - * => B を新規に作成する - * - * 2. A が存在し、B が存在しない場合 - * => A の内容を B にコピーする (警告を表示) - * - * 3. A が存在せず、B が存在する場合 - * => B を使用する - * - * 4. A も B も存在するが、A の方が更新日時が新しい場合 - * => A の内容を B にコピーする (警告を表示) - * - * 5. A も B も存在するが、B の方が更新日時が新しい場合 - * => B を使用する - */ - var startupDirFile = new FileInfo(Path.Combine(Application.StartupPath, "SettingCommon.xml")); - var roamingDirFile = new FileInfo(Path.Combine(roamingDir, "SettingCommon.xml")); - - if (roamingDirFile.Exists && (!startupDirFile.Exists || startupDirFile.LastWriteTime <= roamingDirFile.LastWriteTime)) - { - // 既に Roaming に設定ファイルが存在し、Roaming 内のファイルの方が新しい場合は - // StartupPath に設定ファイルが存在しても無視する - SettingManager.Instance.LoadAll(); - } - else - { - if (startupDirFile.Exists) - { - // StartupPath に設定ファイルが存在し、Roaming 内のファイルよりも新しい場合のみ警告を表示する - var message = string.Format(Properties.Resources.SettingPath_Relocation, Application.StartupPath, MyCommon.SettingPath); - MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information); - } - - // Roaming に設定ファイルを作成 (StartupPath に読み込みに成功した設定ファイルがあれば内容がコピーされる) - SettingManager.Instance.SaveAll(); - } - } - } - - return true; - } - private static bool ShowSettingsDialog(SettingManager settings, IconAssetsManager iconAssets) { using var settingDialog = new AppendSettingDialog(); diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index 8336118f1..c60c0ef05 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -63,8 +63,6 @@ public static class MyCommon public static bool EndingFlag { get; set; } // 終了フラグ - public static string SettingPath { get; set; } = null!; - public enum IconSizes { IconNone = 0, @@ -391,7 +389,7 @@ public static bool ExceptionOut(Exception ex) writer.Write(errorReport); } - var settings = SettingManager.Instance.Common; + var settings = SettingManager.Instance; var mainForm = Application.OpenForms.OfType().FirstOrDefault(); ErrorReport report; @@ -400,15 +398,15 @@ public static bool ExceptionOut(Exception ex) else report = new ErrorReport(errorReport); - report.AnonymousReport = settings.ErrorReportAnonymous; + report.AnonymousReport = settings.Common.ErrorReportAnonymous; OpenErrorReportDialog(mainForm, report); // ダイアログ内で設定が変更されていれば保存する - if (settings.ErrorReportAnonymous != report.AnonymousReport) + if (settings.Common.ErrorReportAnonymous != report.AnonymousReport) { - settings.ErrorReportAnonymous = report.AnonymousReport; - settings.Save(); + settings.Common.ErrorReportAnonymous = report.AnonymousReport; + settings.SaveCommon(); } return false; diff --git a/OpenTween/Setting/SettingAtIdList.cs b/OpenTween/Setting/SettingAtIdList.cs index 6f0eb19fb..08ab3c4f9 100644 --- a/OpenTween/Setting/SettingAtIdList.cs +++ b/OpenTween/Setting/SettingAtIdList.cs @@ -36,14 +36,11 @@ namespace OpenTween public class SettingAtIdList : SettingBase { #region Settingクラス基本 - public static SettingAtIdList Load() - { - var setting = LoadSettings(); - return setting; - } + public static SettingAtIdList Load(string settingsPath) + => LoadSettings(settingsPath); - public void Save() - => SaveSettings(this); + public void Save(string settingsPath) + => SaveSettings(this, settingsPath); public SettingAtIdList() => this.AtIdList = new List(); diff --git a/OpenTween/Setting/SettingBase.cs b/OpenTween/Setting/SettingBase.cs index b6c1be617..d63cec426 100644 --- a/OpenTween/Setting/SettingBase.cs +++ b/OpenTween/Setting/SettingBase.cs @@ -53,11 +53,11 @@ public abstract class SettingBase private static readonly object LockObj = new(); - protected static T LoadSettings(string fileId) + protected static T LoadSettings(string settingsPath, string fileId) { try { - var settingFilePath = GetSettingFilePath(fileId); + var settingFilePath = GetSettingFilePath(settingsPath, fileId); if (!File.Exists(settingFilePath)) { return new T(); @@ -93,7 +93,7 @@ protected static T LoadSettings(string fileId) fs.Position = 0; var xs = new XmlSerializer(typeof(T)); var instance = (T)xs.Deserialize(fs); - MessageBox.Show("File: " + GetSettingFilePath(fileId) + Environment.NewLine + "Use old setting file, because application can't read this setting file."); + MessageBox.Show("File: " + GetSettingFilePath(settingsPath, fileId) + Environment.NewLine + "Use old setting file, because application can't read this setting file."); return instance; } } @@ -101,15 +101,15 @@ protected static T LoadSettings(string fileId) { } } - MessageBox.Show("File: " + GetSettingFilePath(fileId) + Environment.NewLine + "Use default setting, because application can't read this setting file."); + MessageBox.Show("File: " + GetSettingFilePath(settingsPath, fileId) + Environment.NewLine + "Use default setting, because application can't read this setting file."); return new T(); } } - protected static T LoadSettings() - => LoadSettings(""); + protected static T LoadSettings(string settingsPath) + => LoadSettings(settingsPath, ""); - protected static void SaveSettings(T instance, string fileId) + protected static void SaveSettings(T instance, string settingsPath, string fileId) { const int SaveRetryMax = 3; @@ -119,10 +119,10 @@ protected static void SaveSettings(T instance, string fileId) var retryCount = 0; Exception? lastException = null; - var filePath = GetSettingFilePath(fileId); + var filePath = GetSettingFilePath(settingsPath, fileId); do { - var tmpfilePath = GetSettingFilePath("_" + Path.GetRandomFileName()); + var tmpfilePath = GetSettingFilePath(settingsPath, "_" + Path.GetRandomFileName()); try { lock (LockObj) @@ -172,10 +172,10 @@ protected static void SaveSettings(T instance, string fileId) MessageBox.Show("Can't write setting XML.(" + filePath + ")", "Save Settings", MessageBoxButtons.OK); } - protected static void SaveSettings(T instance) - => SaveSettings(instance, ""); + protected static void SaveSettings(T instance, string settingsPath) + => SaveSettings(instance, settingsPath, ""); - public static string GetSettingFilePath(string fileId) - => Path.Combine(MyCommon.SettingPath, typeof(T).Name + fileId + ".xml"); + public static string GetSettingFilePath(string settingsPath, string fileId) + => Path.Combine(settingsPath, typeof(T).Name + fileId + ".xml"); } } diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index 0716f329c..895dce894 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -37,11 +37,11 @@ namespace OpenTween public class SettingCommon : SettingBase { #region "Settingクラス基本" - public static SettingCommon Load() - => LoadSettings(); + public static SettingCommon Load(string settingsPath) + => LoadSettings(settingsPath); - public void Save() - => SaveSettings(this); + public void Save(string settingsPath) + => SaveSettings(this, settingsPath); #endregion public List UserAccounts = new(); diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index 2e3636537..3eb90c481 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -39,11 +39,11 @@ namespace OpenTween public class SettingLocal : SettingBase { #region Settingクラス基本 - public static SettingLocal Load() - => LoadSettings(); + public static SettingLocal Load(string settingsPath) + => LoadSettings(settingsPath); - public void Save() - => SaveSettings(this); + public void Save(string settingsPath) + => SaveSettings(this, settingsPath); #endregion /// diff --git a/OpenTween/Setting/SettingManager.cs b/OpenTween/Setting/SettingManager.cs index 6041f1f22..44babc89b 100644 --- a/OpenTween/Setting/SettingManager.cs +++ b/OpenTween/Setting/SettingManager.cs @@ -23,9 +23,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Windows.Forms; using OpenTween.Connection; using OpenTween.Thumbnail; @@ -33,7 +35,9 @@ namespace OpenTween.Setting { public class SettingManager { - public static SettingManager Instance { get; } = new(); + public static SettingManager Instance { get; internal set; } = new(null!); + + public string SettingsPath { get; set; } public SettingCommon Common { get; internal set; } = new(); @@ -49,6 +53,9 @@ public bool IsIncomplete public bool IsFirstRun { get; private set; } = false; + public SettingManager(string settingsPath) + => this.SettingsPath = settingsPath; + public void LoadAll() { this.LoadCommon(); @@ -61,7 +68,7 @@ public void LoadAll() public void LoadCommon() { - var settings = SettingCommon.Load(); + var settings = SettingCommon.Load(this.SettingsPath); if (settings.UserAccounts == null || settings.UserAccounts.Count == 0) { @@ -84,13 +91,13 @@ public void LoadCommon() } public void LoadLocal() - => this.Local = SettingLocal.Load(); + => this.Local = SettingLocal.Load(this.SettingsPath); public void LoadTabs() - => this.Tabs = SettingTabs.Load(); + => this.Tabs = SettingTabs.Load(this.SettingsPath); public void LoadAtIdList() - => this.AtIdList = SettingAtIdList.Load(); + => this.AtIdList = SettingAtIdList.Load(this.SettingsPath); public void SaveAll() { @@ -101,16 +108,16 @@ public void SaveAll() } public void SaveCommon() - => this.Common.Save(); + => this.Common.Save(this.SettingsPath); public void SaveLocal() - => this.Local.Save(); + => this.Local.Save(this.SettingsPath); public void SaveTabs() - => this.Tabs.Save(); + => this.Tabs.Save(this.SettingsPath); public void SaveAtIdList() - => this.AtIdList.Save(); + => this.AtIdList.Save(this.SettingsPath); public void ApplySettings() { @@ -132,5 +139,100 @@ public void ApplySettings() ShortUrl.Instance.BitlyId = this.Common.BilyUser; ShortUrl.Instance.BitlyKey = this.Common.BitlyPwd; } + + public static string? DetermineSettingsPath(CommandLineArgs args) + { + if (args.TryGetValue("configDir", out var configDir) && !MyCommon.IsNullOrEmpty(configDir)) + { + // 起動オプション /configDir で設定ファイルの参照先を変更できます + if (!Directory.Exists(configDir)) + { + var text = string.Format(Properties.Resources.ConfigDirectoryNotExist, configDir); + MessageBox.Show(text, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error); + return null; + } + + return Path.GetFullPath(configDir); + } + + const string settingCommonFilename = "SettingCommon.xml"; + + // OpenTween.exe と同じディレクトリに設定ファイルを配置する + var startupDir = Application.StartupPath; + var settingCommonPath = Path.Combine(startupDir, settingCommonFilename); + if (CanWriteFile(settingCommonPath)) + return startupDir; + + // 書き込みに失敗した場合 (Program Files 以下に配置されている場合など) + // C:\Users\ユーザー名\AppData\Roaming\OpenTween\ 以下に設定ファイルを作成する + var roamingDir = Path.Combine(new[] + { + Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), + ApplicationSettings.ApplicationName, + }); + Directory.CreateDirectory(roamingDir); + + /* + * 書き込みが制限されたディレクトリ内で起動された場合の設定ファイルの扱い + * + * (A) StartupPath に存在する設定ファイル + * (B) Roaming に存在する設定ファイル + * + * 1. A も B も存在しない場合 + * => B を新規に作成する + * + * 2. A が存在し、B が存在しない場合 + * => A の内容を B にコピーする (警告を表示) + * + * 3. A が存在せず、B が存在する場合 + * => B を使用する + * + * 4. A も B も存在するが、A の方が更新日時が新しい場合 + * => A の内容を B にコピーする (警告を表示) + * + * 5. A も B も存在するが、B の方が更新日時が新しい場合 + * => B を使用する + */ + var startupDirFile = new FileInfo(Path.Combine(startupDir, settingCommonFilename)); + var roamingDirFile = new FileInfo(Path.Combine(roamingDir, settingCommonFilename)); + + if (startupDirFile.Exists && (!roamingDirFile.Exists || startupDirFile.LastWriteTime > roamingDirFile.LastWriteTime)) + { + // StartupPath に設定ファイルが存在し、Roaming 内のファイルよりも新しい場合は警告を表示してファイルをコピーする + var message = string.Format(Properties.Resources.SettingPath_Relocation, startupDir, roamingDir); + MessageBox.Show(message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information); + + var settings = new SettingManager(startupDir); + settings.LoadAll(); + settings.SettingsPath = roamingDir; + settings.SaveAll(); + } + + return roamingDir; + } + + private static bool CanWriteFile(string path) + { + try + { + if (File.Exists(path)) + { + using var stream = File.OpenWrite(path); + return true; + } + else + { + using (var stream = File.OpenWrite(path)) + { + } + File.Delete(path); + return true; + } + } + catch (UnauthorizedAccessException) + { + return false; + } + } } } diff --git a/OpenTween/Setting/SettingTabs.cs b/OpenTween/Setting/SettingTabs.cs index 7721a84ab..c40d091eb 100644 --- a/OpenTween/Setting/SettingTabs.cs +++ b/OpenTween/Setting/SettingTabs.cs @@ -38,11 +38,11 @@ namespace OpenTween public class SettingTabs : SettingBase { #region Settingクラス基本 - public static SettingTabs Load() - => LoadSettings(""); + public static SettingTabs Load(string settingsPath) + => LoadSettings(settingsPath); - public void Save() - => SaveSettings(this); + public void Save(string settingsPath) + => SaveSettings(this, settingsPath); public SettingTabs() => this.Tabs = new List(); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index d8c0b92b1..d0bb502f2 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -4890,8 +4890,8 @@ private void RunTweenUp() var pinfo = new ProcessStartInfo { UseShellExecute = true, - WorkingDirectory = MyCommon.SettingPath, - FileName = Path.Combine(MyCommon.SettingPath, "TweenUp3.exe"), + WorkingDirectory = this.settings.SettingsPath, + FileName = Path.Combine(this.settings.SettingsPath, "TweenUp3.exe"), Arguments = "\"" + Application.StartupPath + "\"", }; From 94448570298f9de234f58e87fc892fbc0055407a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 3 Apr 2022 07:13:52 +0900 Subject: [PATCH 173/402] =?UTF-8?q?=E5=85=AC=E5=BC=8FRT=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E3=81=99=E3=82=8B=E9=96=A2=E9=80=A3=E7=99=BA=E8=A8=80=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=A7RT=E5=85=83=E3=81=AE=E7=99=BA=E8=A8=80?= =?UTF-8?q?=E3=81=8C=E3=82=BF=E3=83=96=E3=81=AB=E8=A1=A8=E7=A4=BA=E3=81=95?= =?UTF-8?q?=E3=82=8C=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Twitter.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 9bf1cbc81..f14179b87 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -989,6 +989,16 @@ internal static PostClass FindTopOfReplyChain(IDictionary posts public async Task GetRelatedResult(bool read, RelatedPostsTabModel tab) { var targetPost = tab.TargetPost; + + if (targetPost.RetweetedId != null) + { + var originalPost = targetPost.Clone(); + originalPost.StatusId = targetPost.RetweetedId.Value; + originalPost.RetweetedId = null; + originalPost.RetweetedBy = null; + targetPost = originalPost; + } + var relPosts = new Dictionary(); if (targetPost.TextFromApi.Contains("@") && targetPost.InReplyToStatusId == null) { From 23fdcb492c595a551295c7dc9b92fc9fe47bb17e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 3 Apr 2022 07:17:15 +0900 Subject: [PATCH 174/402] =?UTF-8?q?=E9=96=A2=E9=80=A3=E7=99=BA=E8=A8=80?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E3=81=A7conversation=5Fid=E3=81=AB=E3=82=88?= =?UTF-8?q?=E3=82=8B=E6=A4=9C=E7=B4=A2=E7=B5=90=E6=9E=9C=E3=82=92=E5=90=AB?= =?UTF-8?q?=E3=82=81=E3=82=8B=E6=A9=9F=E8=83=BD=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Twitter.cs | 39 +++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 1fe0ad63e..e420afdff 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -8,6 +8,7 @@ - 高DPI環境で表示した場合により高解像度のプロフィール画像が取得されるようになります - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります * NEW: 発言のダブルクリック時の動作に「Reply All」(@返信ALL)を追加 + * NEW: 関連発言表示で会話ツリーの最新の発言を取得する機能を追加 * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * CHG: DMが選択されている時は「@返信」「@返信ALL」のどちらも「DM送信」と同じ動作となるように変更 * CHG: 複数のユーザー宛のリプライ時にツイートの先頭にピリオドを加える仕様を廃止 diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index f14179b87..0070f48eb 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -1077,6 +1077,29 @@ public async Task GetRelatedResult(bool read, RelatedPostsTabModel tab) } } + try + { + var firstPost = nextPost; + var posts = await this.GetConversationPosts(firstPost, targetPost) + .ConfigureAwait(false); + + foreach (var post in posts.OrderBy(x => x.StatusId)) + { + if (relPosts.ContainsKey(post.StatusId)) + continue; + + // リプライチェーンが繋がらないツイートは除外 + if (post.InReplyToStatusId == null || !relPosts.ContainsKey(post.InReplyToStatusId.Value)) + continue; + + relPosts.Add(post.StatusId, post); + } + } + catch (WebException ex) + { + lastException = ex; + } + relPosts.Values.ToList().ForEach(p => { var post = p.Clone(); @@ -1092,6 +1115,22 @@ public async Task GetRelatedResult(bool read, RelatedPostsTabModel tab) throw new WebApiException(lastException.Message, lastException); } + private async Task GetConversationPosts(PostClass firstPost, PostClass targetPost) + { + var conversationId = firstPost.StatusId; + var query = $"conversation_id:{conversationId}"; + + if (targetPost.InReplyToUser != null && targetPost.InReplyToUser != targetPost.ScreenName) + query += $" (from:{targetPost.ScreenName} to:{targetPost.InReplyToUser}) OR (from:{targetPost.InReplyToUser} to:{targetPost.ScreenName})"; + else + query += $" from:{targetPost.ScreenName} to:{targetPost.ScreenName}"; + + var statuses = await this.Api.SearchTweets(query, count: 100) + .ConfigureAwait(false); + + return statuses.Statuses.Select(x => this.CreatePostsFromStatusData(x)).ToArray(); + } + public async Task GetSearch(bool read, PublicSearchTabModel tab, bool more) { var count = GetApiResultCount(MyCommon.WORKERTYPE.PublicSearch, more, false); From 725449ec86f250a4af02c7bad621af378367345d Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 22 Apr 2022 23:19:09 +0900 Subject: [PATCH 175/402] =?UTF-8?q?SettingLocal.xml=E3=81=ABScaleDimension?= =?UTF-8?q?=E3=81=8C=E7=84=A1=E3=81=84=E5=A0=B4=E5=90=88=E3=81=AF=E5=B8=B8?= =?UTF-8?q?=E3=81=AB96dpi=E3=81=A8=E3=81=97=E3=81=A6=E6=89=B1=E3=81=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 初回起動時および Tween から設定をコピーしてきた場合にウィンドウサイズを適切にスケールさせる --- OpenTween/Setting/SettingLocal.cs | 2 +- OpenTween/Tween.cs | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index 3eb90c481..6bf9c4e03 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -49,7 +49,7 @@ public void Save(string settingsPath) /// /// ウィンドウサイズ等の保存時のDPI /// - public SizeF ScaleDimension = SizeF.Empty; + public SizeF ScaleDimension { get; set; } = new(96f, 96f); public Point FormLocation = new(0, 0); public int SplitterDistance = 200; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index d0bb502f2..d680561f6 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -904,10 +904,6 @@ private void ListTab_DrawItem(object sender, DrawItemEventArgs e) private void LoadConfig() { - // v1.2.4 以前の設定には ScaleDimension の項目がないため、現在の DPI と同じとして扱う - if (this.settings.Local.ScaleDimension.IsEmpty) - this.settings.Local.ScaleDimension = this.CurrentAutoScaleDimensions; - this.statuses.LoadTabsFromSettings(this.settings.Tabs); this.statuses.AddDefaultTabs(); } From 0fe27a37f3816695795021238d8491fa20a6e1e6 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 23 Apr 2022 00:13:27 +0900 Subject: [PATCH 176/402] =?UTF-8?q?=E3=82=A6=E3=82=A3=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=82=A6=E3=82=B5=E3=82=A4=E3=82=BA=E7=AD=89=E3=81=AE=E8=A8=AD?= =?UTF-8?q?=E5=AE=9A=E3=81=AE=E5=88=9D=E6=9C=9F=E5=80=A4=E3=82=92=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Setting/SettingLocal.cs | 11 +++++++---- OpenTween/Tween.cs | 12 ++---------- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index e420afdff..d4c8f70ab 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -13,6 +13,7 @@ * CHG: DMが選択されている時は「@返信」「@返信ALL」のどちらも「DM送信」と同じ動作となるように変更 * CHG: 複数のユーザー宛のリプライ時にツイートの先頭にピリオドを加える仕様を廃止 * CHG: 発言一覧上でEnterキーを押した時の動作をダブルクリック時と同じとなるように変更 + * CHG: 初回起動時のウィンドウサイズなどの初期値を変更 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) * FIX: 等幅フォント表示を有効にした場合に背景色の設定が全面に適用されない不具合を修正 (thx @StoutAmmo!) diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index 6bf9c4e03..ec3ee5cf1 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -51,9 +51,11 @@ public void Save(string settingsPath) /// public SizeF ScaleDimension { get; set; } = new(96f, 96f); - public Point FormLocation = new(0, 0); - public int SplitterDistance = 200; - public Size FormSize = new(600, 500); + public Point FormLocation { get; set; } = new(50, 50); + + public int SplitterDistance { get; set; } = 320; + + public Size FormSize { get; set; } = new(700, 500); /// /// 文末ステータス @@ -171,7 +173,8 @@ public int DisplayIndex8 public string ProxyUser = ""; public bool StatusMultiline = false; public int StatusTextHeight = 38; - public int PreviewDistance = -1; + + public int PreviewDistance { get; set; } = 500; public string? FontUnreadStr { get; set; } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index d680561f6..aa1d7b402 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -697,16 +697,8 @@ ThumbnailGenerator thumbGenerator this.TopMost = this.settings.Common.AlwaysTop; this.mySpDis = ScaleBy(configScaleFactor.Height, this.settings.Local.SplitterDistance); this.mySpDis2 = ScaleBy(configScaleFactor.Height, this.settings.Local.StatusTextHeight); - if (this.settings.Local.PreviewDistance == -1) - { - this.mySpDis3 = this.mySize.Width - ScaleBy(this.CurrentScaleFactor.Width, 150); - if (this.mySpDis3 < 1) this.mySpDis3 = ScaleBy(this.CurrentScaleFactor.Width, 50); - this.settings.Local.PreviewDistance = this.mySpDis3; - } - else - { - this.mySpDis3 = ScaleBy(configScaleFactor.Width, this.settings.Local.PreviewDistance); - } + this.mySpDis3 = ScaleBy(configScaleFactor.Width, this.settings.Local.PreviewDistance); + this.PlaySoundMenuItem.Checked = this.settings.Common.PlaySound; this.PlaySoundFileMenuItem.Checked = this.settings.Common.PlaySound; // 入力欄 From 3bbd05c26864e614610d84cb1de5ce62e8dad58f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 23 Apr 2022 05:49:30 +0900 Subject: [PATCH 177/402] =?UTF-8?q?PostStateImageList=E3=81=AE=E3=82=A2?= =?UTF-8?q?=E3=82=A4=E3=82=B3=E3=83=B3=E3=83=AA=E3=82=BD=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=82=92=20Properties/Resources.resx=20=E3=81=AB=E7=A7=BB?= =?UTF-8?q?=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/OpenTween.csproj | 15 +++ OpenTween/Properties/Resources.Designer.cs | 150 +++++++++++++++++++++ OpenTween/Properties/Resources.resx | 15 +++ OpenTween/Tween.Designer.cs | 22 --- OpenTween/Tween.cs | 27 +++- OpenTween/Tween.resx | 135 ------------------- 6 files changed, 205 insertions(+), 159 deletions(-) diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index da0ee3d47..f9fc03bcd 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -761,6 +761,21 @@ + + + + + + + + + + + + + + + diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 201f93ff3..4884f6e9a 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -1861,6 +1861,156 @@ internal static string PostPictureWarn6 { } } + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState00 { + get { + object obj = ResourceManager.GetObject("PostState00", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState01 { + get { + object obj = ResourceManager.GetObject("PostState01", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState02 { + get { + object obj = ResourceManager.GetObject("PostState02", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState03 { + get { + object obj = ResourceManager.GetObject("PostState03", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState04 { + get { + object obj = ResourceManager.GetObject("PostState04", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState05 { + get { + object obj = ResourceManager.GetObject("PostState05", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState06 { + get { + object obj = ResourceManager.GetObject("PostState06", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState07 { + get { + object obj = ResourceManager.GetObject("PostState07", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState08 { + get { + object obj = ResourceManager.GetObject("PostState08", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState09 { + get { + object obj = ResourceManager.GetObject("PostState09", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState10 { + get { + object obj = ResourceManager.GetObject("PostState10", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState11 { + get { + object obj = ResourceManager.GetObject("PostState11", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState12 { + get { + object obj = ResourceManager.GetObject("PostState12", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState13 { + get { + object obj = ResourceManager.GetObject("PostState13", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// (アイコン) に類似した型 System.Drawing.Icon のローカライズされたリソースを検索します。 + /// + internal static System.Drawing.Icon PostState14 { + get { + object obj = ResourceManager.GetObject("PostState14", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + /// /// POST完了 に類似しているローカライズされた文字列を検索します。 /// diff --git a/OpenTween/Properties/Resources.resx b/OpenTween/Properties/Resources.resx index dfc9c8587..bd8363720 100644 --- a/OpenTween/Properties/Resources.resx +++ b/OpenTween/Properties/Resources.resx @@ -211,6 +211,21 @@ ファイル名: {2} 使用可能な投稿先: {1} なし + ..\Resources\S0.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S1.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S2.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S3.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S4.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S5.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S6.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S7.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S8.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S9.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S10.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S11.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S12.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S13.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + ..\Resources\S14.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a POST完了 Recent更新中... 更新間隔には数値(0または30~6000)を指定してください。 diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index 4ffb5d8fb..3ba11e3fd 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -255,7 +255,6 @@ private void InitializeComponent() this.ToolStripMenuItem6 = new System.Windows.Forms.ToolStripMenuItem(); this.ToolTip1 = new System.Windows.Forms.ToolTip(this.components); this.TimerRefreshIcon = new System.Windows.Forms.Timer(this.components); - this.PostStateImageList = new System.Windows.Forms.ImageList(this.components); this.ContextMenuColumnHeader = new System.Windows.Forms.ContextMenuStrip(this.components); this.IconSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.IconSizeNoneToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -2035,26 +2034,6 @@ private void InitializeComponent() // this.TimerRefreshIcon.Tick += new System.EventHandler(this.TimerRefreshIcon_Tick); // - // PostStateImageList - // - this.PostStateImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("PostStateImageList.ImageStream"))); - this.PostStateImageList.TransparentColor = System.Drawing.Color.Transparent; - this.PostStateImageList.Images.SetKeyName(0, "S0.ico"); - this.PostStateImageList.Images.SetKeyName(1, "S1.ico"); - this.PostStateImageList.Images.SetKeyName(2, "S2.ico"); - this.PostStateImageList.Images.SetKeyName(3, "S3.ico"); - this.PostStateImageList.Images.SetKeyName(4, "S4.ico"); - this.PostStateImageList.Images.SetKeyName(5, "S5.ico"); - this.PostStateImageList.Images.SetKeyName(6, "S6.ico"); - this.PostStateImageList.Images.SetKeyName(7, "S7.ico"); - this.PostStateImageList.Images.SetKeyName(8, "S8.ico"); - this.PostStateImageList.Images.SetKeyName(9, "S9.ico"); - this.PostStateImageList.Images.SetKeyName(10, "S10.ico"); - this.PostStateImageList.Images.SetKeyName(11, "S11.ico"); - this.PostStateImageList.Images.SetKeyName(12, "S12.ico"); - this.PostStateImageList.Images.SetKeyName(13, "S13.ico"); - this.PostStateImageList.Images.SetKeyName(14, "S14.ico"); - // // ContextMenuColumnHeader // this.ContextMenuColumnHeader.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -2367,7 +2346,6 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripMenuItem ToolStripMenuItem6; internal System.Windows.Forms.ToolTip ToolTip1; internal System.Windows.Forms.Timer TimerRefreshIcon; - internal System.Windows.Forms.ImageList PostStateImageList; private System.Windows.Forms.ToolStripMenuItem ProtectTabMenuItem; private System.Windows.Forms.ToolStripMenuItem ProtectTbMenuItem; private TweetThumbnail tweetThumbnail1; diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index aa1d7b402..1fec1d54d 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -4547,8 +4547,31 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) { var stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + realIconSize.Width + 2, iconRect.Y), realStateSize), itemRect); if (stateRect.Width > 0) - e.Graphics.DrawImage(this.PostStateImageList.Images[item.StateIndex], stateRect); - } + e.Graphics.DrawIcon(this.GetPostStateIcon(item.StateIndex), stateRect); + } + } + + private Icon GetPostStateIcon(int stateIndex) + { + return stateIndex switch + { + 0 => Properties.Resources.PostState00, + 1 => Properties.Resources.PostState01, + 2 => Properties.Resources.PostState02, + 3 => Properties.Resources.PostState03, + 4 => Properties.Resources.PostState04, + 5 => Properties.Resources.PostState05, + 6 => Properties.Resources.PostState06, + 7 => Properties.Resources.PostState07, + 8 => Properties.Resources.PostState08, + 9 => Properties.Resources.PostState09, + 10 => Properties.Resources.PostState10, + 11 => Properties.Resources.PostState11, + 12 => Properties.Resources.PostState12, + 13 => Properties.Resources.PostState13, + 14 => Properties.Resources.PostState14, + _ => throw new IndexOutOfRangeException(), + }; } protected override void ScaleControl(SizeF factor, BoundsSpecified specified) diff --git a/OpenTween/Tween.resx b/OpenTween/Tween.resx index b171150a7..2bfdb2387 100644 --- a/OpenTween/Tween.resx +++ b/OpenTween/Tween.resx @@ -254,8 +254,6 @@ 1 PostModeMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - PostStateImageList - System.Windows.Forms.ImageList, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 PreventSmsCommandMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 PreventSmsCommandPullDownMenuItem @@ -864,139 +862,6 @@ Post 225, 22 投稿設定 - - AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w - LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 - ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACW - HQAAAk1TRnQBSQFMAgEBDwEAAZABAQGQAQEBEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA - AwABQAMAAQEBAAEgBgABQP8AIwADwAH/A8AB/xAAA8AB/yQAA8AB/wPAAf8QAAPAAf8kAAPAAf8DwAH/ - EAADwAH/YAABTgGZAv8BTgGZAv8QAAFDAZkBQwH/A8AB/yAAAU4BmQL/AU4BmQL/EAABQwGZAUMB/wPA - Af8gAAFOAZkC/wFOAZkC/xAAAUMBmQFDAf8DwAH/WAADwAH/AU4BmQL/AU4BmQL/A8AB/wPAAf8DwAH/ - CAABQwGZAUMB/wPAAf8DwAH/FAADwAH/AU4BmQL/AU4BmQL/A8AB/wPAAf8DwAH/CAABQwGZAUMB/wPA - Af8DwAH/FAADwAH/AU4BmQL/AU4BmQL/A8AB/wPAAf8DwAH/CAABQwGZAUMB/wPAAf8DwAH/UAABTgGZ - Av8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8DwAH/BAABQwGZAUMB/wFDAZkBQwH/AUMBmQFD - Af8DwAH/A8AB/wwAAU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/A8AB/wQAAUMBmQFD - Af8BQwGZAUMB/wFDAZkBQwH/A8AB/wPAAf8MAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFO - AZkC/wPAAf8EAAFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wPAAf8DwAH/TAABTgGZAv8BTgGZAv8BTgGZ - Av8BTgGZAv8BTgGZAv8BTgGZAv8DwAH/AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZ - AUMB/wPAAf8MAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wPAAf8BQwGZAUMB/wFD - AZkBQwH/AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/A8AB/wwAAU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/ - AU4BmQL/AU4BmQL/A8AB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf8DwAH/ - TAABTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8DwAH/AUMBmQFDAf8BQwGZAUMB/wQA - AUMBmQFDAf8BQwGZAUMB/wPAAf8MAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wPA - Af8BQwGZAUMB/wFDAZkBQwH/BAABQwGZAUMB/wFDAZkBQwH/A8AB/wwAAU4BmQL/AU4BmQL/AU4BmQL/ - AU4BmQL/AU4BmQL/AU4BmQL/A8AB/wFDAZkBQwH/AUMBmQFDAf8EAAFDAZkBQwH/AUMBmQFDAf8DwAH/ - TAABTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8EAAFDAZkBQwH/AUMBmQFDAf8BQwGZ - AUMB/wFDAZkBQwH/AUMBmQFDAf8QAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wQA - AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/xAAAU4BmQL/AU4BmQL/AU4BmQL/ - AU4BmQL/AU4BmQL/AU4BmQL/BAABQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/ - cAABQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf80AAFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/zQAAUMBmQFD - Af8BQwGZAUMB/wFDAZkBQwH/WAADwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf9MAAPAAf8DwAH/FAADwAH/ - A8AB/wPAAf8DwAH/A8AB/wPAAf8MAAPAAf8DwAH/UAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8DwAH/SAAB/wGZAUMC/wGZAUMB/wPAAf8DwAH/DAABmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8BmQKBAf8DwAH/CAAB/wGZAUMC/wGZAUMB/wPAAf8DwAH/TAABmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8BmQKBAf8BmQKBAf8DwAH/RAAB/wGZAUMC/wGZAUMC/wGZAUMC/wGZAUMB/wPAAf8DwAH/ - CAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8DwAH/BAAB/wGZAUMC/wGZAUMC/wGZ - AUMC/wGZAUMB/wPAAf8DwAH/SAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8DwAH/ - QAAB/wGZAUMC/wGZAUMB/wQAAf8BmQFDAv8BmQFDAv8BmQFDAf8DwAH/CAABmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8BmQKBAf8BmQKBAf8DwAL/AZkBQwL/AZkBQwH/BAAB/wGZAUMC/wGZAUMC/wGZAUMB/wPA - Af9IAAGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/0QAAf8BmQFDAf8MAAH/AZkBQwL/ - AZkBQwH/A8AB/wPAAf8EAAGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wQAAf8BmQFD - Af8MAAH/AZkBQwL/AZkBQwH/A8AB/wPAAf9IAAGZAoEB/wQAA8AB/wGZAoEB/1wAAf8BmQFDAv8BmQFD - Af8DwAH/CAABmQKBAf8EAAPAAf8BmQKBAf8cAAH/AZkBQwL/AZkBQwH/A8AB/0wAAZkCgQH/AZkCgQH/ - ZAAB/wGZAUMB/xAAAZkCgQH/AZkCgQH/JAAB/wGZAUMB//8AcQADwAH/PAADwAH/PAADwAH/JAADwAH/ - A8AB/xAAA8AB/zgAAUMBmQFDAf8DwAH/OAABQwGZAUMB/wPAAf84AAFDAZkBQwH/A8AB/yAAAU4BmQL/ - AU4BmQL/EAABQwGZAUMB/wPAAf84AAFDAZkBQwH/A8AB/wPAAf80AAFDAZkBQwH/A8AB/wPAAf80AAFD - AZkBQwH/A8AB/wPAAf8UAAPAAf8BTgGZAv8BTgGZAv8DwAH/A8AB/wPAAf8IAAFDAZkBQwH/A8AB/wPA - Af8wAAFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wPAAf8DwAH/LAABQwGZAUMB/wFDAZkBQwH/AUMBmQFD - Af8DwAH/A8AB/ywAAUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/A8AB/wPAAf8MAAFOAZkC/wFOAZkC/wFO - AZkC/wFOAZkC/wFOAZkC/wFOAZkC/wPAAf8EAAFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wPAAf8DwAH/ - KAABQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/A8AB/ygAAUMBmQFDAf8BQwGZ - AUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wPAAf8oAAFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wFD - AZkBQwH/AUMBmQFDAf8DwAH/DAABTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8DwAH/ - AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/wPAAf8oAAFDAZkBQwH/AUMBmQFD - Af8EAAFDAZkBQwH/AUMBmQFDAf8DwAH/KAABQwGZAUMB/wFDAZkBQwH/BAABQwGZAUMB/wFDAZkBQwH/ - A8AB/ygAAUMBmQFDAf8BQwGZAUMB/wQAAUMBmQFDAf8BQwGZAUMB/wPAAf8MAAFOAZkC/wFOAZkC/wFO - AZkC/wFOAZkC/wFOAZkC/wFOAZkC/wPAAf8BQwGZAUMB/wFDAZkBQwH/BAABQwGZAUMB/wFDAZkBQwH/ - A8AB/ygAAUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/ywAAUMBmQFDAf8BQwGZ - AUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB/ywAAUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/AUMBmQFD - Af8BQwGZAUMB/xAAAU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/BAABQwGZAUMB/wFD - AZkBQwH/AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/MAABQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf80AAFD - AZkBQwH/AUMBmQFDAf8BQwGZAUMB/zQAAUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/NAABQwGZAUMB/wFD - AZkBQwH/AUMBmQFDAf8YAAPAAf8DwAH/A8AB/wPAAf8DwAH/A8AB/0wAA8AB/wPAAf8UAAPAAf8DwAH/ - A8AB/wPAAf8DwAH/A8AB/wwAA8AB/wPAAf9QAAGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZ - AoEB/wPAAf9IAAH/AZkBQwL/AZkBQwH/A8AB/wPAAf8MAAGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZ - AoEB/wGZAoEB/wPAAf8IAAH/AZkBQwL/AZkBQwH/A8AB/wPAAf9MAAGZAoEB/wGZAoEB/wGZAoEB/wGZ - AoEB/wGZAoEB/wGZAoEB/wPAAf9EAAH/AZkBQwL/AZkBQwL/AZkBQwL/AZkBQwH/A8AB/wPAAf8IAAGZ - AoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wPAAf8EAAH/AZkBQwL/AZkBQwL/AZkBQwL/ - AZkBQwH/A8AB/wPAAf9IAAGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wPAAf9AAAH/ - AZkBQwL/AZkBQwH/BAAB/wGZAUMC/wGZAUMC/wGZAUMB/wPAAf8IAAGZAoEB/wGZAoEB/wGZAoEB/wGZ - AoEB/wGZAoEB/wGZAoEB/wPAAv8BmQFDAv8BmQFDAf8EAAH/AZkBQwL/AZkBQwL/AZkBQwH/A8AB/0gA - AZkCgQH/AZkCgQH/AZkCgQH/AZkCgQH/AZkCgQH/AZkCgQH/RAAB/wGZAUMB/wwAAf8BmQFDAv8BmQFD - Af8DwAH/A8AB/wQAAZkCgQH/AZkCgQH/AZkCgQH/AZkCgQH/AZkCgQH/AZkCgQH/BAAB/wGZAUMB/wwA - Af8BmQFDAv8BmQFDAf8DwAH/A8AB/0gAAZkCgQH/BAADwAH/AZkCgQH/XAAB/wGZAUMC/wGZAUMB/wPA - Af8IAAGZAoEB/wQAA8AB/wGZAoEB/xwAAf8BmQFDAv8BmQFDAf8DwAH/TAABmQKBAf8BmQKBAf9kAAH/ - AZkBQwH/EAABmQKBAf8BmQKBAf8kAAH/AZkBQwH//wBZAAPAAf8DwAH/OAADwAH/A8AB/zgAA8AB/wPA - Af9QAAPAAf8gAAFOAZkC/wFOAZkC/zgAAU4BmQL/AU4BmQL/OAABTgGZAv8BTgGZAv9QAAFDAZkBQwH/ - A8AB/xgAA8AB/wFOAZkC/wFOAZkC/wPAAf8DwAH/A8AB/ygAA8AB/wFOAZkC/wFOAZkC/wPAAf8DwAH/ - A8AB/ygAA8AB/wFOAZkC/wFOAZkC/wPAAf8DwAH/A8AB/0gAAUMBmQFDAf8DwAH/A8AB/xAAAU4BmQL/ - AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/A8AB/yQAAU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/ - AU4BmQL/AU4BmQL/A8AB/yQAAU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/A8AB/0QA - AUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/A8AB/wPAAf8MAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFO - AZkC/wFOAZkC/wPAAf8kAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wPAAf8kAAFO - AZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wPAAf9AAAFDAZkBQwH/AUMBmQFDAf8BQwGZ - AUMB/wFDAZkBQwH/AUMBmQFDAf8DwAH/DAABTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZ - Av8DwAH/JAABTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8DwAH/JAABTgGZAv8BTgGZ - Av8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8DwAH/QAABQwGZAUMB/wFDAZkBQwH/BAABQwGZAUMB/wFD - AZkBQwH/A8AB/wwAAU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/AU4BmQL/KAABTgGZAv8BTgGZ - Av8BTgGZAv8BTgGZAv8BTgGZAv8BTgGZAv8oAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFO - AZkC/0QAAUMBmQFDAf8BQwGZAUMB/wFDAZkBQwH/AUMBmQFDAf8BQwGZAUMB//AAAUMBmQFDAf8BQwGZ - AUMB/wFDAZkBQwH/GAADwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf9MAAPAAf8DwAH/FAADwAH/A8AB/wPA - Af8DwAH/A8AB/wPAAf8MAAPAAf8DwAH/UAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8DwAH/SAAB/wGZAUMC/wGZAUMB/wPAAf8DwAH/DAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8DwAH/CAAB/wGZAUMC/wGZAUMB/wPAAf8DwAH/TAABmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8BmQKBAf8DwAH/RAAB/wGZAUMC/wGZAUMC/wGZAUMC/wGZAUMB/wPAAf8DwAH/CAABmQKB - Af8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8DwAH/BAAB/wGZAUMC/wGZAUMC/wGZAUMC/wGZ - AUMB/wPAAf8DwAH/SAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8DwAH/QAAB/wGZ - AUMC/wGZAUMB/wQAAf8BmQFDAv8BmQFDAv8BmQFDAf8DwAH/CAABmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8BmQKBAf8DwAL/AZkBQwL/AZkBQwH/BAAB/wGZAUMC/wGZAUMC/wGZAUMB/wPAAf9IAAGZ - AoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/0QAAf8BmQFDAf8MAAH/AZkBQwL/AZkBQwH/ - A8AB/wPAAf8EAAGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wQAAf8BmQFDAf8MAAH/ - AZkBQwL/AZkBQwH/A8AB/wPAAf9IAAGZAoEB/wQAA8AB/wGZAoEB/1wAAf8BmQFDAv8BmQFDAf8DwAH/ - CAABmQKBAf8EAAPAAf8BmQKBAf8cAAH/AZkBQwL/AZkBQwH/A8AB/0wAAZkCgQH/AZkCgQH/ZAAB/wGZ - AUMB/xAAAZkCgQH/AZkCgQH/JAAB/wGZAUMB//8A/wAaAAPAAf8DwAH/9AABTgGZAv8BTgGZAv/wAAPA - Af8BTgGZAv8BTgGZAv8DwAH/A8AB/wPAAf/kAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFO - AZkC/wPAAf/kAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wPAAf/kAAFOAZkC/wFO - AZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wPAAf/kAAFOAZkC/wFOAZkC/wFOAZkC/wFOAZkC/wFO - AZkC/wFOAZkC//8ALQADwAH/A8AB/wPAAf8DwAH/A8AB/wPAAf9MAAPAAf8DwAH/FAADwAH/A8AB/wPA - Af8DwAH/A8AB/wPAAf8MAAPAAf8DwAH/UAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8DwAH/SAAB/wGZAUMC/wGZAUMB/wPAAf8DwAH/DAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8DwAH/CAAB/wGZAUMC/wGZAUMB/wPAAf8DwAH/TAABmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8BmQKBAf8DwAH/RAAB/wGZAUMC/wGZAUMC/wGZAUMC/wGZAUMB/wPAAf8DwAH/CAABmQKB - Af8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8DwAH/BAAB/wGZAUMC/wGZAUMC/wGZAUMC/wGZ - AUMB/wPAAf8DwAH/SAABmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8BmQKBAf8DwAH/QAAB/wGZ - AUMC/wGZAUMB/wQAAf8BmQFDAv8BmQFDAv8BmQFDAf8DwAH/CAABmQKBAf8BmQKBAf8BmQKBAf8BmQKB - Af8BmQKBAf8BmQKBAf8DwAL/AZkBQwL/AZkBQwH/BAAB/wGZAUMC/wGZAUMC/wGZAUMB/wPAAf9IAAGZ - AoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/0QAAf8BmQFDAf8MAAH/AZkBQwL/AZkBQwH/ - A8AB/wPAAf8EAAGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wGZAoEB/wQAAf8BmQFDAf8MAAH/ - AZkBQwL/AZkBQwH/A8AB/wPAAf9IAAGZAoEB/wQAA8AB/wGZAoEB/1wAAf8BmQFDAv8BmQFDAf8DwAH/ - CAABmQKBAf8EAAPAAf8BmQKBAf8cAAH/AZkBQwL/AZkBQwH/A8AB/0wAAZkCgQH/AZkCgQH/ZAAB/wGZ - AUMB/xAAAZkCgQH/AZkCgQH/JAAB/wGZAUMB/0gAAUIBTQE+BwABPgMAASgDAAFAAwABQAMAAQEBAAEB - BgABAhYAA/8BAAb/AgAB8wHfAfMB3wHzAd8CAAHnAZ8B5wGfAecBnwIAAYEBjwGBAY8BgQGPAgABAQEH - AQEBBwEBAQcDAAEHAQABBwEAAQcDAAFHAQABRwEAAUcCAAECAQ8BAgEPAQIBDwIAAf8BHwH/AR8B/wEf - AgABgQL/Ac8BgQHPAgABAQL/AYcBAQGHAgABAQL/AQMBAQEDAgABAQH/Af4BQwEAAUMCAAEDAf8B/gHh - AQIB4QIAAacC/wHxAacB8QIAAc8C/wH7Ac8B+wIACf8B3wH/Ad8B/wHfAfMB3wH/AZ8B/wGfAf8BnwHn - AZ8B/wGPAf8BjwH/AY8BgQGPAf8BBwH/AQcB/wEHAQEBBwH+AQcB/gEHAf4BBwEAAQcB/gFHAf4BRwH+ - AUcBAAFHAf4BDwH+AQ8B/gEPAQIBDwH/AR8B/wEfAf8BHwH/AR8BgQL/Ac8BgQHPAv8BAQL/AYcBAQGH - Av8BAQL/AQMBAQEDAv8BAQH/Af4BQwEAAUMC/wEDAf8B/gHhAQIB4QL/AacC/wHxAacB8QL/Ac8C/wH7 - Ac8B+wr/AfMB/wHzAf8B8wL/Ad8B5wH/AecB/wHnAv8BnwGBAf8BgQH/AYEC/wGPAQEB/wEBAf8BAQL/ - AQcBAQH/AQEB/wEBAf8B/gEHAQEB/wEBAf8BAQH/Af4BRwEDAf8BAwH/AQMB/wH+AQ8H/wEfAYEC/wHP - AYEBzwL/AQEC/wGHAQEBhwL/AQEC/wEDAQEBAwL/AQEB/wH+AUMBAAFDAv8BAwH/Af4B4QECAeEC/wGn - Av8B8QGnAfEC/wHPAv8B+wHPAfsQ/wHzB/8B5wf/AYEH/wEBB/8BAQf/AQEH/wEDCf8BgQL/Ac8BgQHP - Av8BAQL/AYcBAQGHAv8BAQL/AQMBAQEDAv8BAQH/Af4BQwEAAUMC/wEDAf8B/gHhAQIB4QL/AacC/wHx - AacB8QL/Ac8C/wH7Ac8B+wL/Cw== - - 363, 17 246, 22 SMSコマンドを回避する 257, 22 From 7d07941e75aa2a597aa61af143d801b059cbc4a0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 23 Apr 2022 05:52:15 +0900 Subject: [PATCH 178/402] =?UTF-8?q?Control=E6=B4=BE=E7=94=9F=E3=82=AF?= =?UTF-8?q?=E3=83=A9=E3=82=B9=E3=81=A7setter=E3=82=92=E6=8C=81=E3=81=A4?= =?UTF-8?q?=E3=83=97=E3=83=AD=E3=83=91=E3=83=86=E3=82=A3=E3=81=ABBrowsable?= =?UTF-8?q?,=20DesignerSerializationVisibility=E3=82=92=E6=8C=87=E5=AE=9A?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/DetailsListView.cs | 3 +++ OpenTween/ToolStripAPIGauge.cs | 1 + OpenTween/Tween.Designer.cs | 1 - OpenTween/TweetDetailsView.cs | 4 ++++ 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index 097982c7e..2f020d1cb 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -42,6 +42,7 @@ public sealed class DetailsListView : ListView { private Rectangle changeBounds; + [DefaultValue(null)] public ContextMenuStrip? ColumnHeaderContextMenuStrip { get; set; } public event EventHandler? VScrolled; @@ -63,6 +64,8 @@ public DetailsListView() /// Items[idx].Selected の設定では mark が設定されるが、SelectedIndices.Add(idx) では設定されないため、 /// 主に後者と合わせて使用する /// + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public int SelectionMark { get => NativeMethods.ListView_GetSelectionMark(this.Handle); diff --git a/OpenTween/ToolStripAPIGauge.cs b/OpenTween/ToolStripAPIGauge.cs index 2eaa8e1b4..c567e05dd 100644 --- a/OpenTween/ToolStripAPIGauge.cs +++ b/OpenTween/ToolStripAPIGauge.cs @@ -89,6 +89,7 @@ private set /// API エンドポイント名 /// [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public string? ApiEndpoint { get => this.apiEndpoint; diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index 3ba11e3fd..b1aae02e1 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -343,7 +343,6 @@ private void InitializeComponent() // // toolStripApiGauge // - this.toolStripApiGauge.ApiEndpoint = null; this.toolStripApiGauge.BorderSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.Right; this.toolStripApiGauge.DoubleClickEnabled = true; this.toolStripApiGauge.Name = "toolStripApiGauge"; diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index cc0fc0822..4f8a5350f 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -55,11 +55,15 @@ private ImageCache IconCache => this.iconCache ?? throw this.NotInitializedException(); /// のダンプを表示するか + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public bool DumpPostClass { get; set; } /// 現在表示中の発言 public PostClass? CurrentPost { get; private set; } + [Browsable(false)] + [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ThemeManager Theme { get => this.themeManager ?? throw this.NotInitializedException(); From 7304cd77387395adc5867898f179bcbbf1c195fe Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 23 Apr 2022 16:52:20 +0900 Subject: [PATCH 179/402] =?UTF-8?q?TweenMain.anchorPost=E3=82=92TabModel?= =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=82=B9=E3=82=BF=E3=83=B3=E3=82=B9=E3=81=A7?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/TabModelTest.cs | 62 +++++++++++++++++ OpenTween/Models/TabModel.cs | 20 ++++++ OpenTween/Tween.cs | 96 ++++++++++++-------------- 3 files changed, 125 insertions(+), 53 deletions(-) diff --git a/OpenTween.Tests/Models/TabModelTest.cs b/OpenTween.Tests/Models/TabModelTest.cs index bf865fb44..2cf139d1a 100644 --- a/OpenTween.Tests/Models/TabModelTest.cs +++ b/OpenTween.Tests/Models/TabModelTest.cs @@ -32,6 +32,68 @@ namespace OpenTween.Models { public class TabModelTest { + [Fact] + public void AnchorPost_Test() + { + var tab = new PublicSearchTabModel("search"); + + var posts = new[] + { + new PostClass { StatusId = 100L }, + new PostClass { StatusId = 110L }, + }; + tab.AddPostQueue(posts[0]); + tab.AddPostQueue(posts[1]); + tab.AddSubmit(); + + Assert.Null(tab.AnchorStatusId); + Assert.Null(tab.AnchorPost); + + tab.AnchorPost = posts[1]; + + Assert.Equal(110L, tab.AnchorStatusId); + Assert.Equal(110L, tab.AnchorPost.StatusId); + } + + [Fact] + public void AnchorPost_DeletedTest() + { + var tab = new PublicSearchTabModel("search"); + + var posts = new[] + { + new PostClass { StatusId = 100L }, + }; + tab.AddPostQueue(posts[0]); + tab.AddSubmit(); + tab.AnchorPost = posts[0]; + + Assert.Equal(100L, tab.AnchorPost.StatusId); + + tab.EnqueueRemovePost(100L, setIsDeleted: true); + tab.RemoveSubmit(); + + Assert.Null(tab.AnchorPost); + } + + [Fact] + public void ClearAnchor_Test() + { + var tab = new PublicSearchTabModel("search"); + + var posts = new[] + { + new PostClass { StatusId = 100L }, + }; + tab.AddPostQueue(posts[0]); + tab.AddSubmit(); + tab.AnchorPost = posts[0]; + + Assert.Equal(100L, tab.AnchorPost.StatusId); + tab.ClearAnchor(); + Assert.Null(tab.AnchorPost); + } + [Fact] public void SelectPosts_Test() { diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index fde2cfe6b..d9c054279 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -100,6 +100,23 @@ public int SelectedIndex } } + public long? AnchorStatusId { get; set; } + + public PostClass? AnchorPost + { + get + { + if (this.AnchorStatusId == null) + return null; + + if (!this.Posts.TryGetValue(this.AnchorStatusId.Value, out var post)) + return null; + + return post; + } + set => this.AnchorStatusId = value?.StatusId; + } + private IndexedSortedSet ids = new(); private ConcurrentQueue addQueue = new(); private readonly ConcurrentQueue removeQueue = new(); @@ -190,6 +207,9 @@ bool IsValidIndex(int index) this.selectedStatusIds = statusIds; } + public void ClearAnchor() + => this.AnchorStatusId = null; + public virtual void ClearIDs() { this.ids.Clear(); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 1fec1d54d..8fea228f5 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -168,9 +168,6 @@ public partial class TweenMain : OTBaseForm private readonly ImageList listViewImageList = new(); // ListViewItemの高さ変更用 - private PostClass? anchorPost; - private bool anchorFlag; // true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画) - /// 発言履歴 private readonly List history = new(); @@ -1517,13 +1514,9 @@ private void ColorizeList() { // Index:更新対象のListviewItem.Index。Colorを返す。 // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - PostClass? post; - if (this.anchorFlag) - post = this.anchorPost; - else - post = this.CurrentPost; - - if (post == null) return; + var post = this.CurrentTab.AnchorPost ?? this.CurrentPost; + if (post == null) + return; var listCache = this.listItemCache; if (listCache == null) @@ -1545,13 +1538,9 @@ private void ColorizeList(ListViewItem item, PostClass post) { // Index:更新対象のListviewItem.Index。Colorを返す。 // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - PostClass? basePost; - if (this.anchorFlag) - basePost = this.anchorPost; - else - basePost = this.CurrentPost; - - if (basePost == null) return; + var basePost = this.CurrentTab.AnchorPost ?? this.CurrentPost; + if (basePost == null) + return; if (item.Index == -1) item.BackColor = this.JudgeColor(basePost, post); @@ -5122,7 +5111,7 @@ private async void ListTab_KeyDown(object sender, KeyEventArgs e) } if (e.Control || e.Shift || e.Alt) - this.anchorFlag = false; + tab.ClearAnchor(); if (this.CommonKeyDown(e.KeyData, FocusedControl.ListTab, out var asyncTask)) { @@ -5176,7 +5165,7 @@ private void InitializeShortcuts() .NotFocusedOn(FocusedControl.StatusText) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.JumpUnreadMenuItem_Click(this.JumpUnreadMenuItem, EventArgs.Empty); }), @@ -5184,7 +5173,7 @@ private void InitializeShortcuts() .NotFocusedOn(FocusedControl.StatusText) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.ShowRelatedStatusesMenuItem_Click(this.ShowRelatedStatusesMenuItem, EventArgs.Empty); }), @@ -5217,7 +5206,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.GoPost(forward: true); }), @@ -5225,7 +5214,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.GoPost(forward: false); }), @@ -5233,7 +5222,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.MoveTop(); }), @@ -5241,7 +5230,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.GoNextTab(forward: true); }), @@ -5249,7 +5238,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.GoNextTab(forward: false); }), @@ -5258,7 +5247,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); return this.GoInReplyToPostTree(); }), @@ -5267,7 +5256,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.GoBackInReplyToPostTree(); }), @@ -5275,7 +5264,7 @@ private void InitializeShortcuts() .FocusedOn(FocusedControl.ListTab) .Do(() => { - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); var tab = this.CurrentTab; var tabtype = tab.TabType; if (tabtype == MyCommon.TabUsageType.Related || tabtype == MyCommon.TabUsageType.UserTimeline || tabtype == MyCommon.TabUsageType.PublicSearch || tabtype == MyCommon.TabUsageType.SearchResults) @@ -5288,7 +5277,7 @@ private void InitializeShortcuts() // 上下キー, PageUp/Downキー, Home/Endキー は既定の動作を残しつつアンカー初期化 ShortcutCommand.Create(Keys.Up, Keys.Down, Keys.PageUp, Keys.PageDown, Keys.Home, Keys.End) .FocusedOn(FocusedControl.ListTab) - .Do(() => this.anchorFlag = false, preventDefault: false), + .Do(() => this.CurrentTab.ClearAnchor(), preventDefault: false), // PreviewKeyDownEventArgs.IsInputKey を true にしてスクロールを発生させる ShortcutCommand.Create(Keys.Up, Keys.Down) @@ -6013,29 +6002,28 @@ private void GoRelPost(bool forward) stp = -1; } - if (!this.anchorFlag) + var anchorPost = tab.AnchorPost; + if (anchorPost == null) { var currentPost = this.CurrentPost; - if (currentPost == null) return; - this.anchorPost = currentPost; - this.anchorFlag = true; - } - else - { - if (this.anchorPost == null) return; + if (currentPost == null) + return; + + anchorPost = currentPost; + tab.AnchorPost = currentPost; } for (var idx = fIdx; idx != toIdx; idx += stp) { var post = tab[idx]; - if (post.ScreenName == this.anchorPost.ScreenName || - post.RetweetedBy == this.anchorPost.ScreenName || - post.ScreenName == this.anchorPost.RetweetedBy || - (!MyCommon.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == this.anchorPost.RetweetedBy) || - this.anchorPost.ReplyToList.Any(x => x.UserId == post.UserId) || - this.anchorPost.ReplyToList.Any(x => x.UserId == post.RetweetedByUserId) || - post.ReplyToList.Any(x => x.UserId == this.anchorPost.UserId) || - post.ReplyToList.Any(x => x.UserId == this.anchorPost.RetweetedByUserId)) + if (post.ScreenName == anchorPost.ScreenName || + post.RetweetedBy == anchorPost.ScreenName || + post.ScreenName == anchorPost.RetweetedBy || + (!MyCommon.IsNullOrEmpty(post.RetweetedBy) && post.RetweetedBy == anchorPost.RetweetedBy) || + anchorPost.ReplyToList.Any(x => x.UserId == post.UserId) || + anchorPost.ReplyToList.Any(x => x.UserId == post.RetweetedByUserId) || + post.ReplyToList.Any(x => x.UserId == anchorPost.UserId) || + post.ReplyToList.Any(x => x.UserId == anchorPost.RetweetedByUserId)) { var listView = this.CurrentListView; this.SelectListItem(listView, idx); @@ -6047,9 +6035,13 @@ private void GoRelPost(bool forward) private void GoAnchor() { - if (this.anchorPost == null) return; - var idx = this.CurrentTab.IndexOf(this.anchorPost.StatusId); - if (idx == -1) return; + var anchorStatusId = this.CurrentTab.AnchorStatusId; + if (anchorStatusId == null) + return; + + var idx = this.CurrentTab.IndexOf(anchorStatusId.Value); + if (idx == -1) + return; var listView = this.CurrentListView; this.SelectListItem(listView, idx); @@ -6501,7 +6493,7 @@ private bool GoDirectMessage(long statusId) } private void MyList_MouseClick(object sender, MouseEventArgs e) - => this.anchorFlag = false; + => this.CurrentTab.ClearAnchor(); private void StatusText_Enter(object sender, EventArgs e) { @@ -7749,8 +7741,7 @@ private void ClearTab(string tabName, bool showWarning) this.statuses.ClearTabIds(tabName); if (this.CurrentTabName == tabName) { - this.anchorPost = null; - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); this.PurgeListViewItemCache(); } @@ -8739,8 +8730,7 @@ private void ListTabSelect(TabPage tab) var listView = this.CurrentListView; - this.anchorPost = null; - this.anchorFlag = false; + this.CurrentTab.ClearAnchor(); if (this.iconCol) { From 92f0a891310a4c7222ef50c94cf2eabf76575510 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 23 Apr 2022 23:40:52 +0900 Subject: [PATCH 180/402] =?UTF-8?q?ImageListViewItem=E3=82=92=E5=89=8A?= =?UTF-8?q?=E9=99=A4=E3=81=97=E9=80=9A=E5=B8=B8=E3=81=AEListViewItem?= =?UTF-8?q?=E3=81=AE=E3=81=BF=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ImageListViewItem.cs | 139 --------------------------------- OpenTween/OpenTween.csproj | 1 - OpenTween/Tween.cs | 88 +++++++++++++-------- 3 files changed, 57 insertions(+), 171 deletions(-) delete mode 100644 OpenTween/ImageListViewItem.cs diff --git a/OpenTween/ImageListViewItem.cs b/OpenTween/ImageListViewItem.cs deleted file mode 100644 index d66d6a614..000000000 --- a/OpenTween/ImageListViewItem.cs +++ /dev/null @@ -1,139 +0,0 @@ -// OpenTween - Client of Twitter -// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) -// (c) 2008-2011 Moz (@syo68k) -// (c) 2008-2011 takeshik (@takeshik) -// (c) 2010-2011 anis774 (@anis774) -// (c) 2010-2011 fantasticswallow (@f_swallow) -// (c) 2011 Egtra (@egtra) -// All rights reserved. -// -// This file is part of OpenTween. -// -// This program is free software; you can redistribute it and/or modify it -// under the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 3 of the License, or (at your option) -// any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License along -// with this program. If not, see , or write to -// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -// Boston, MA 02110-1301, USA. - -#nullable enable - -using System; -using System.Net.Http; -using System.Runtime.Serialization; -using System.Threading.Tasks; -using System.Windows.Forms; - -namespace OpenTween -{ - [Serializable] - public class ImageListViewItem : ListViewItem - { - protected readonly ImageCache? imageCache; - protected readonly string? imageUrl; - - /// - /// 状態表示に使用するアイコンのインデックスを取得・設定する。 - /// - /// - /// StateImageIndex は不必要な処理が挟まるため、使用しないようにする。 - /// - public int StateIndex { get; set; } - - private readonly WeakReference imageReference = new(null); - private Task? imageTask = null; - - public event EventHandler? ImageDownloaded; - - public ImageListViewItem(string[] items) - : this(items, null, null, 0) - { - } - - public ImageListViewItem(string[] items, ImageCache? imageCache, string? imageNormalUrl, int imageSize) - : base(items) - { - this.imageCache = imageCache; - this.imageUrl = this.CreateImageUrl(imageNormalUrl, imageSize); - this.StateIndex = -1; - - var image = this.imageUrl != null ? imageCache?.TryGetFromCache(this.imageUrl) : null; - - if (image != null) - this.imageReference.Target = image; - } - - protected ImageListViewItem(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } - - private string? CreateImageUrl(string? normalImageUrl, int imageSize) - { - if (MyCommon.IsNullOrEmpty(normalImageUrl)) - return null; - - if (imageSize <= 0) - return null; - - var sizeName = Twitter.DecideProfileImageSize(imageSize); - return Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); - } - - public Task GetImageAsync() - { - if (this.imageTask == null || this.imageTask.IsCompleted) - { - this.imageTask = this.GetImageAsyncInternal(); - } - - return this.imageTask; - } - - private async Task GetImageAsyncInternal() - { - if (MyCommon.IsNullOrEmpty(this.imageUrl) || this.imageCache == null) - return; - - if (this.imageReference.Target != null) - return; - - try - { - var image = await this.imageCache.DownloadImageAsync(this.imageUrl); - - this.imageReference.Target = image; - - if (this.ListView == null || !this.ListView.Created || this.ListView.IsDisposed) - return; - - if (this.Index < this.ListView.VirtualListSize) - { - this.ListView.RedrawItems(this.Index, this.Index, true); - - this.ImageDownloaded?.Invoke(this, EventArgs.Empty); - } - } - catch (HttpRequestException) - { - } - catch (InvalidImageException) - { - } - catch (TaskCanceledException) - { - } - } - - public MemoryImage Image - => (MemoryImage)this.imageReference.Target; - } -} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index f9fc03bcd..999fe438c 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -410,7 +410,6 @@ - Form diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 8fea228f5..7dff25104 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -4188,7 +4188,7 @@ private void MyList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventA { // 不正な要求に対する間に合わせの応答 string[] sitem = { "", "", "", "", "", "", "", "" }; - e.Item = new ImageListViewItem(sitem); + e.Item = new ListViewItem(sitem); } } @@ -4237,9 +4237,7 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) if (post.FavoritedCount > 0) mk.Append("+" + post.FavoritedCount); - var scaledIconSz = (int)Math.Ceiling(this.iconSz * this.CurrentScaleFactor.Width); - - ImageListViewItem itm; + ListViewItem itm; if (post.RetweetedId == null) { string[] sitem = @@ -4253,7 +4251,7 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) mk.ToString(), post.Source, }; - itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl, scaledIconSz); + itm = new ListViewItem(sitem); } else { @@ -4268,9 +4266,8 @@ private ListViewItem CreateItem(TabModel tab, PostClass post) mk.ToString(), post.Source, }; - itm = new ImageListViewItem(sitem, this.iconCache, post.ImageUrl, scaledIconSz); + itm = new ListViewItem(sitem); } - itm.StateIndex = post.StateIndex; itm.Tag = post; var read = post.IsRead; @@ -4485,7 +4482,7 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) { if (this.iconSz == 0) return; - var item = (ImageListViewItem)e.Item; + var item = e.Item; // e.Bounds.Leftが常に0を指すから自前で計算 var itemRect = item.Bounds; @@ -4505,41 +4502,70 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) var realIconSize = new SizeF(this.iconSz * this.CurrentScaleFactor.Width, this.iconSz * this.CurrentScaleFactor.Height).ToSize(); var realStateSize = new SizeF(16 * this.CurrentScaleFactor.Width, 16 * this.CurrentScaleFactor.Height).ToSize(); - Rectangle iconRect; - var img = item.Image; + var iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, realIconSize), itemRect); + iconRect.Offset(0, Math.Max(0, (itemRect.Height - realIconSize.Height) / 2)); + + var post = this.CurrentTab[item.Index]; + var img = this.LoadListViewIconLazy(item.ListView, post, realIconSize.Width); if (img != null) { - iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, realIconSize), itemRect); - iconRect.Offset(0, Math.Max(0, (itemRect.Height - realIconSize.Height) / 2)); - - if (iconRect.Width > 0) + e.Graphics.FillRectangle(Brushes.White, iconRect); + e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; + try + { + e.Graphics.DrawImage(img.Image, iconRect); + } + catch (ArgumentException) { - e.Graphics.FillRectangle(Brushes.White, iconRect); - e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; - try - { - e.Graphics.DrawImage(img.Image, iconRect); - } - catch (ArgumentException) - { - } } - } - else - { - iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, new Size(1, 1)), itemRect); - - item.GetImageAsync(); } - if (item.StateIndex > -1) + if (post.StateIndex > -1) { var stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + realIconSize.Width + 2, iconRect.Y), realStateSize), itemRect); if (stateRect.Width > 0) - e.Graphics.DrawIcon(this.GetPostStateIcon(item.StateIndex), stateRect); + e.Graphics.DrawIcon(this.GetPostStateIcon(post.StateIndex), stateRect); } } + private MemoryImage? LoadListViewIconLazy(ListView listView, PostClass post, int scaledIconSize) + { + if (scaledIconSize <= 0) + return null; + + var normalImageUrl = post.ImageUrl; + if (MyCommon.IsNullOrEmpty(normalImageUrl)) + return null; + + var sizeName = Twitter.DecideProfileImageSize(scaledIconSize); + var cachedImage = this.iconCache.TryGetLargerOrSameSizeFromCache(normalImageUrl, sizeName); + if (cachedImage != null) + return cachedImage; + + // キャッシュにない画像の場合は読み込みが完了してから再描画する + _ = Task.Run(async () => + { + var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); + var image = await this.iconCache.DownloadImageAsync(imageUrl); + + await this.InvokeAsync(() => + { + if (listView.IsDisposed) + return; + + if (listView != this.CurrentListView) + return; + + // ロード中に index の指す行が変化している可能性がある + var newIndex = this.CurrentTab.IndexOf(post.StatusId); + if (newIndex != -1) + listView.RedrawItems(newIndex, newIndex, true); + }); + }); + + return null; + } + private Icon GetPostStateIcon(int stateIndex) { return stateIndex switch From af6e2260abbbc13816d3218d27d8d9e062c6d456 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 23 Apr 2022 23:44:27 +0900 Subject: [PATCH 181/402] =?UTF-8?q?TweenMain=E3=81=AEbrsHighLight=E3=81=8A?= =?UTF-8?q?=E3=82=88=E3=81=B3brsDeactiveSelection=E3=82=92ThemeManager?= =?UTF-8?q?=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ThemeManager.cs | 9 +++++++++ OpenTween/Tween.cs | 11 ++--------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/OpenTween/ThemeManager.cs b/OpenTween/ThemeManager.cs index 9b1d118c3..9564125ce 100644 --- a/OpenTween/ThemeManager.cs +++ b/OpenTween/ThemeManager.cs @@ -115,6 +115,11 @@ public sealed class ThemeManager : IDisposable public Brush BrushListBackcolor { get; } + public Brush BrushHighLight { get; } + + /// Listにフォーカスがないときの選択行の背景色 + public Brush BrushDeactiveSelection { get; } + public ThemeManager(SettingLocal settingLocal) { var fontConverter = new FontConverter(); @@ -193,6 +198,8 @@ public ThemeManager(SettingLocal settingLocal) this.BrushAtFromTarget = new SolidBrush(this.ColorAtFromTarget); this.BrushAtTo = new SolidBrush(this.ColorAtTo); this.BrushListBackcolor = new SolidBrush(this.ColorListBackcolor); + this.BrushHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight)); + this.BrushDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace)); } public void Dispose() @@ -211,6 +218,8 @@ public void Dispose() this.BrushAtFromTarget.Dispose(); this.BrushAtTo.Dispose(); this.BrushListBackcolor.Dispose(); + this.BrushHighLight.Dispose(); + this.BrushDeactiveSelection.Dispose(); this.IsDisposed = true; } diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 7dff25104..64c2c997b 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -184,11 +184,6 @@ public partial class TweenMain : OTBaseForm private readonly List favTimestamps = new(); // 以下DrawItem関連 - private readonly SolidBrush brsHighLight = new(Color.FromKnownColor(KnownColor.Highlight)); - - /// Listにフォーカスないときの選択行の背景色 - private readonly SolidBrush brsDeactiveSelection = new(Color.FromKnownColor(KnownColor.ButtonFace)); - private readonly StringFormat sfTab = new(); ////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -354,9 +349,7 @@ protected override void Dispose(bool disposing) this.SearchDialog.Dispose(); this.urlDialog.Dispose(); this.listViewImageList.Dispose(); - this.brsHighLight.Dispose(); this.themeManager.Dispose(); - this.brsDeactiveSelection?.Dispose(); this.sfTab.Dispose(); this.timelineScheduler.Dispose(); @@ -4352,9 +4345,9 @@ private void MyList_DrawItem(object sender, DrawListViewItemEventArgs e) { // 選択中の行 if (((Control)sender).Focused) - brs2 = this.brsHighLight; + brs2 = this.themeManager.BrushHighLight; else - brs2 = this.brsDeactiveSelection; + brs2 = this.themeManager.BrushDeactiveSelection; } e.Graphics.FillRectangle(brs2, e.Bounds); e.DrawFocusRectangle(); From 2b79ab36031da4001ac90d8908d7886869301ae6 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 23 Apr 2022 23:53:28 +0900 Subject: [PATCH 182/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE2Column=E8=A1=A8=E7=A4=BA=E6=99=82=E3=81=AB=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=99=E3=82=8B=E3=83=95=E3=82=A9=E3=83=B3=E3=83=88?= =?UTF-8?q?=E3=82=92ThemeManager=E3=81=A7=E7=AE=A1=E7=90=86=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/ThemeManager.cs | 10 ++++++++++ OpenTween/Tween.cs | 9 +++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/OpenTween/ThemeManager.cs b/OpenTween/ThemeManager.cs index 9564125ce..8bac6fbd3 100644 --- a/OpenTween/ThemeManager.cs +++ b/OpenTween/ThemeManager.cs @@ -38,9 +38,13 @@ public sealed class ThemeManager : IDisposable /// 未読用フォント public Font FontUnread { get; } + public Font FontUnreadBold { get; } + /// 既読用フォント public Font FontReaded { get; } + public Font FontReadedBold { get; } + /// 発言詳細部用フォント public Font FontDetail { get; } @@ -127,9 +131,13 @@ public ThemeManager(SettingLocal settingLocal) this.FontUnread = ConvertStringToFont(fontConverter, settingLocal.FontUnreadStr) ?? new(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline); + this.FontUnreadBold = new(this.FontUnread, FontStyle.Bold); + this.FontReaded = ConvertStringToFont(fontConverter, settingLocal.FontReadStr) ?? SystemFonts.DefaultFont; + this.FontReadedBold = new(this.FontReaded, FontStyle.Bold); + this.FontDetail = ConvertStringToFont(fontConverter, settingLocal.FontDetailStr) ?? SystemFonts.DefaultFont; @@ -208,7 +216,9 @@ public void Dispose() return; this.FontUnread.Dispose(); + this.FontUnreadBold.Dispose(); this.FontReaded.Dispose(); + this.FontReadedBold.Dispose(); this.FontDetail.Dispose(); this.FontInputFont.Dispose(); this.BrushSelf.Dispose(); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 64c2c997b..997f88735 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -4400,7 +4400,12 @@ private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) rctB.Width = e.Header.Width; rctB.Height = fontHeight; - using var fnt = new Font(e.Item.Font, FontStyle.Bold); + Font fontBold; + if (e.Item.Font.Equals(this.themeManager.FontUnread)) + fontBold = this.themeManager.FontUnreadBold; + else + fontBold = this.themeManager.FontReadedBold; + var formatFlags1 = TextFormatFlags.WordBreak | TextFormatFlags.EndEllipsis | TextFormatFlags.GlyphOverhangPadding | @@ -4422,7 +4427,7 @@ private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) TextRenderer.DrawText( e.Graphics, e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]", - fnt, + fontBold, rctB, color, formatFlags2); From d9a31c03eed831b41300200e766d5fb531badf3a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Apr 2022 00:21:59 +0900 Subject: [PATCH 183/402] =?UTF-8?q?InvokeAsync=E3=83=A1=E3=82=BD=E3=83=83?= =?UTF-8?q?=E3=83=89=E3=82=92OTBaseForm=E3=81=8B=E3=82=89Extensions?= =?UTF-8?q?=E3=81=AB=E7=A7=BB=E5=8B=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/OTBaseFormTest.cs | 59 ------------------------------- OpenTween/Extensions.cs | 37 +++++++++++++++++++ OpenTween/OTBaseForm.cs | 41 --------------------- 3 files changed, 37 insertions(+), 100 deletions(-) diff --git a/OpenTween.Tests/OTBaseFormTest.cs b/OpenTween.Tests/OTBaseFormTest.cs index e89f26148..d8ded2720 100644 --- a/OpenTween.Tests/OTBaseFormTest.cs +++ b/OpenTween.Tests/OTBaseFormTest.cs @@ -42,65 +42,6 @@ public OTBaseFormTest() protected void SetupSynchronizationContext() => WindowsFormsSynchronizationContext.AutoInstall = false; - [Fact] - public async Task InvokeAsync_Test() - { - using var form = new TestForm(); - await Task.Run(async () => - { - await form.InvokeAsync(() => form.Text = "hoge"); - }); - - Assert.Equal("hoge", form.Text); - } - - [Fact] - public async Task InvokeAsync_ReturnValueTest() - { - using var form = new TestForm(); - form.Text = "hoge"; - - await Task.Run(async () => - { - var ret = await form.InvokeAsync(() => form.Text); - Assert.Equal("hoge", ret); - }); - } - - [Fact] - public async Task InvokeAsync_TaskTest() - { - using var form = new TestForm(); - await Task.Run(async () => - { - await form.InvokeAsync(async () => - { - await Task.Delay(1); - form.Text = "hoge"; - }); - }); - - Assert.Equal("hoge", form.Text); - } - - [Fact] - public async Task InvokeAsync_TaskWithValueTest() - { - using var form = new TestForm(); - form.Text = "hoge"; - - await Task.Run(async () => - { - var ret = await form.InvokeAsync(async () => - { - await Task.Delay(1); - return form.Text; - }); - - Assert.Equal("hoge", ret); - }); - } - [Fact] public void ScaleChildControl_ListViewTest() { diff --git a/OpenTween/Extensions.cs b/OpenTween/Extensions.cs index 788fed1e8..294a9e03e 100644 --- a/OpenTween/Extensions.cs +++ b/OpenTween/Extensions.cs @@ -46,6 +46,43 @@ public static string GetSelectedText(this WebBrowser webBrowser) return selectedText; } + public static Task InvokeAsync(this Control control, Action x) + { + return control.InvokeAsync(new Func(() => + { + x(); + return 0; + })); + } + + public static Task InvokeAsync(this Control control, Func x) + => control.InvokeAsync(x).Unwrap(); + + public static Task InvokeAsync(this Control control, Func> x) + => control.InvokeAsync>(x).Unwrap(); + + /// + /// メソッドのTask版みたいなやつ + /// + public static Task InvokeAsync(this Control control, Func x) + { + var tcs = new TaskCompletionSource(); + control.BeginInvoke(() => + { + try + { + var ret = x(); + tcs.SetResult(ret); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + }); + + return tcs.Task; + } + public static ReadLockTransaction BeginReadTransaction(this ReaderWriterLockSlim lockObj) => new(lockObj); diff --git a/OpenTween/OTBaseForm.cs b/OpenTween/OTBaseForm.cs index 8a0c58882..982057193 100644 --- a/OpenTween/OTBaseForm.cs +++ b/OpenTween/OTBaseForm.cs @@ -54,12 +54,9 @@ public class OTBaseForm : Form /// public SizeF CurrentScaleFactor { get; private set; } - private readonly SynchronizationContext synchronizationContext; - protected OTBaseForm() { this.CurrentScaleFactor = new SizeF(1.0f, 1.0f); - this.synchronizationContext = SynchronizationContext.Current; this.Load += (o, e) => { @@ -69,44 +66,6 @@ protected OTBaseForm() }; } - public Task InvokeAsync(Action x) - { - return this.InvokeAsync(new Func(() => - { - x(); - return 0; - })); - } - - public Task InvokeAsync(Func x) - => this.InvokeAsync(x).Unwrap(); - - public Task InvokeAsync(Func> x) - => this.InvokeAsync>(x).Unwrap(); - - /// - /// メソッドのTask版みたいなやつ - /// - public Task InvokeAsync(Func x) - { - var tcs = new TaskCompletionSource(); - this.synchronizationContext.Post(_ => - { - try - { - var ret = x(); - tcs.SetResult(ret); - } - catch (Exception ex) - { - tcs.SetException(ex); - } - }, - null); - - return tcs.Task; - } - /// /// source で指定されたフォントのスタイルを維持しつつ GlobalFont に置き換えた Font を返します /// From 3fb41b79a498eb3a16c6b0287dd424fb916ce709 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Apr 2022 02:16:18 +0900 Subject: [PATCH 184/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AEOwnerDraw=E3=81=AB=E9=96=A2=E3=81=99=E3=82=8B=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92TimelineListViewDrawer=E3=82=AF=E3=83=A9?= =?UTF-8?q?=E3=82=B9=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/OpenTween.csproj | 1 + OpenTween/TimelineListViewDrawer.cs | 388 ++++++++++++++++++++++++++++ OpenTween/Tween.cs | 370 +++----------------------- 3 files changed, 430 insertions(+), 329 deletions(-) create mode 100644 OpenTween/TimelineListViewDrawer.cs diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 999fe438c..dba7afc86 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -202,6 +202,7 @@ + UserControl diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs new file mode 100644 index 000000000..176b222c9 --- /dev/null +++ b/OpenTween/TimelineListViewDrawer.cs @@ -0,0 +1,388 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) +// (c) 2008-2011 Moz (@syo68k) +// (c) 2008-2011 takeshik (@takeshik) +// (c) 2010-2011 anis774 (@anis774) +// (c) 2010-2011 fantasticswallow (@f_swallow) +// (c) 2011 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Drawing; +using System.Threading.Tasks; +using System.Windows.Forms; +using OpenTween.Models; +using OpenTween.OpenTweenCustomControl; + +namespace OpenTween +{ + public sealed class TimelineListViewDrawer : IDisposable + { + public bool IsDisposed { get; private set; } = false; + + public ThemeManager Theme { get; set; } + + public MyCommon.IconSizes IconSize + { + get => this.iconSize; + set + { + if (this.iconSize == value) + return; + + this.iconSize = value; + this.ApplyIconSize(); + } + } + + private bool Use2ColumnsMode + => this.IconSize == MyCommon.IconSizes.Icon48_2; + + private int IconSizeNumeric + => this.IconSize switch + { + MyCommon.IconSizes.Icon16 => 16, + MyCommon.IconSizes.Icon24 => 26, // 24x24の場合に26と指定しているのはMSゴシック系フォントのための仕様 + MyCommon.IconSizes.Icon48 => 48, + MyCommon.IconSizes.Icon48_2 => 48, + _ => 0, + }; + + private readonly DetailsListView listView; + private readonly TabModel tab; + private readonly ImageCache iconCache; + private readonly ImageList listViewImageList = new(); // ListViewItemの高さ変更用 + private MyCommon.IconSizes iconSize; + + public TimelineListViewDrawer(DetailsListView listView, TabModel tab, ImageCache iconCache, ThemeManager theme) + { + this.listView = listView; + this.tab = tab; + this.iconCache = iconCache; + this.Theme = theme; + + this.RegisterHandlers(); + this.listView.SmallImageList = this.listViewImageList; + this.listView.OwnerDraw = true; + } + + private void RegisterHandlers() + { + this.listView.DrawItem += this.ListView_DrawItem; + this.listView.DrawSubItem += this.ListView_DrawSubItem; + } + + private void UnregisterHandlers() + { + this.listView.DrawItem -= this.ListView_DrawItem; + this.listView.DrawSubItem -= this.ListView_DrawSubItem; + } + + private void ApplyIconSize() + { + // ディスプレイの DPI 設定を考慮したサイズを設定する + var scaledIconHeight = this.IconSize != MyCommon.IconSizes.IconNone + ? this.listView.LogicalToDeviceUnits(this.IconSizeNumeric) + : 1; + + this.listViewImageList.ImageSize = new(1, scaledIconHeight); + } + + private void DrawListViewItemIcon(DrawListViewItemEventArgs e) + { + if (this.IconSize == 0) return; + + var item = e.Item; + + // e.Bounds.Leftが常に0を指すから自前で計算 + var itemRect = item.Bounds; + var col0 = e.Item.ListView.Columns[0]; + itemRect.Width = col0.Width; + + if (col0.DisplayIndex > 0) + { + foreach (ColumnHeader clm in e.Item.ListView.Columns) + { + if (clm.DisplayIndex < col0.DisplayIndex) + itemRect.X += clm.Width; + } + } + + // ディスプレイの DPI 設定を考慮したアイコンサイズ + var scaleFactor = this.listView.DeviceDpi / 96f; + var scaledIconSize = new SizeF(this.IconSizeNumeric * scaleFactor, this.IconSizeNumeric * scaleFactor).ToSize(); + var scaledStateSize = new SizeF(16 * scaleFactor, 16 * scaleFactor).ToSize(); + + var iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, scaledIconSize), itemRect); + iconRect.Offset(0, Math.Max(0, (itemRect.Height - scaledIconSize.Height) / 2)); + + var post = this.tab[item.Index]; + var img = this.LoadListViewIconLazy(post, scaledIconSize.Width); + if (img != null) + { + e.Graphics.FillRectangle(Brushes.White, iconRect); + e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; + try + { + e.Graphics.DrawImage(img.Image, iconRect); + } + catch (ArgumentException) + { + } + } + + if (post.StateIndex > -1) + { + var stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + scaledIconSize.Width + 2, iconRect.Y), scaledStateSize), itemRect); + if (stateRect.Width > 0) + e.Graphics.DrawIcon(this.GetPostStateIcon(post.StateIndex), stateRect); + } + } + + private MemoryImage? LoadListViewIconLazy(PostClass post, int scaledIconSize) + { + if (scaledIconSize <= 0) + return null; + + var normalImageUrl = post.ImageUrl; + if (MyCommon.IsNullOrEmpty(normalImageUrl)) + return null; + + var sizeName = Twitter.DecideProfileImageSize(scaledIconSize); + var cachedImage = this.iconCache.TryGetLargerOrSameSizeFromCache(normalImageUrl, sizeName); + if (cachedImage != null) + return cachedImage; + + // キャッシュにない画像の場合は読み込みが完了してから再描画する + _ = Task.Run(async () => + { + var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); + var image = await this.iconCache.DownloadImageAsync(imageUrl); + + await this.listView.InvokeAsync(() => + { + if (this.listView.IsDisposed) + return; + + // ロード中に index の指す行が変化している可能性がある + var newIndex = this.tab.IndexOf(post.StatusId); + if (newIndex != -1) + this.listView.RedrawItems(newIndex, newIndex, true); + }); + }); + + return null; + } + + private Icon GetPostStateIcon(int stateIndex) + { + return stateIndex switch + { + 0 => Properties.Resources.PostState00, + 1 => Properties.Resources.PostState01, + 2 => Properties.Resources.PostState02, + 3 => Properties.Resources.PostState03, + 4 => Properties.Resources.PostState04, + 5 => Properties.Resources.PostState05, + 6 => Properties.Resources.PostState06, + 7 => Properties.Resources.PostState07, + 8 => Properties.Resources.PostState08, + 9 => Properties.Resources.PostState09, + 10 => Properties.Resources.PostState10, + 11 => Properties.Resources.PostState11, + 12 => Properties.Resources.PostState12, + 13 => Properties.Resources.PostState13, + 14 => Properties.Resources.PostState14, + _ => throw new IndexOutOfRangeException(), + }; + } + + private void ListView_DrawItem(object sender, DrawListViewItemEventArgs e) + { + if (e.State == 0) return; + e.DrawDefault = false; + + Brush brs2; + if (!e.Item.Selected) // e.ItemStateでうまく判定できない??? + { + if (e.Item.BackColor == this.Theme.ColorSelf) + brs2 = this.Theme.BrushSelf; + else if (e.Item.BackColor == this.Theme.ColorAtSelf) + brs2 = this.Theme.BrushAtSelf; + else if (e.Item.BackColor == this.Theme.ColorTarget) + brs2 = this.Theme.BrushTarget; + else if (e.Item.BackColor == this.Theme.ColorAtTarget) + brs2 = this.Theme.BrushAtTarget; + else if (e.Item.BackColor == this.Theme.ColorAtFromTarget) + brs2 = this.Theme.BrushAtFromTarget; + else if (e.Item.BackColor == this.Theme.ColorAtTo) + brs2 = this.Theme.BrushAtTo; + else + brs2 = this.Theme.BrushListBackcolor; + } + else + { + // 選択中の行 + if (((Control)sender).Focused) + brs2 = this.Theme.BrushHighLight; + else + brs2 = this.Theme.BrushDeactiveSelection; + } + e.Graphics.FillRectangle(brs2, e.Bounds); + e.DrawFocusRectangle(); + this.DrawListViewItemIcon(e); + } + + private void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) + { + if (e.ItemState == 0) return; + + if (e.ColumnIndex > 0) + { + // アイコン以外の列 + var post = (PostClass)e.Item.Tag; + + RectangleF rct = e.Bounds; + rct.Width = e.Header.Width; + var fontHeight = e.Item.Font.Height; + if (this.Use2ColumnsMode) + { + rct.Y += fontHeight; + rct.Height -= fontHeight; + } + + var drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, fontHeight, out var heightDiff)); + + // フォントの高さの半分を足してるのは保険。無くてもいいかも。 + if (this.Use2ColumnsMode || drawLineCount > 1) + { + if (heightDiff < fontHeight * 0.7) + { + // 最終行が70%以上欠けていたら、最終行は表示しない + rct.Height = (fontHeight * drawLineCount) - 1; + } + else + { + drawLineCount += 1; + } + } + + if (rct.Width > 0) + { + var color = (!e.Item.Selected) ? e.Item.ForeColor : // 選択されていない行 + ((Control)sender).Focused ? this.Theme.ColorHighLight : // 選択中の行 + this.Theme.ColorUnread; + + if (this.Use2ColumnsMode) + { + var rctB = e.Bounds; + rctB.Width = e.Header.Width; + rctB.Height = fontHeight; + + Font fontBold; + if (e.Item.Font.Equals(this.Theme.FontUnread)) + fontBold = this.Theme.FontUnreadBold; + else + fontBold = this.Theme.FontReadedBold; + + var formatFlags1 = TextFormatFlags.WordBreak | + TextFormatFlags.EndEllipsis | + TextFormatFlags.GlyphOverhangPadding | + TextFormatFlags.NoPrefix; + + TextRenderer.DrawText( + e.Graphics, + post.IsDeleted ? "(DELETED)" : post.TextSingleLine, + e.Item.Font, + Rectangle.Round(rct), + color, + formatFlags1); + + var formatFlags2 = TextFormatFlags.SingleLine | + TextFormatFlags.EndEllipsis | + TextFormatFlags.GlyphOverhangPadding | + TextFormatFlags.NoPrefix; + + TextRenderer.DrawText( + e.Graphics, + e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]", + fontBold, + rctB, + color, + formatFlags2); + } + else + { + string text; + if (e.ColumnIndex != 2) + text = e.SubItem.Text; + else + text = post.IsDeleted ? "(DELETED)" : post.TextSingleLine; + + if (drawLineCount == 1) + { + var formatFlags = TextFormatFlags.SingleLine | + TextFormatFlags.EndEllipsis | + TextFormatFlags.GlyphOverhangPadding | + TextFormatFlags.NoPrefix | + TextFormatFlags.VerticalCenter; + + TextRenderer.DrawText( + e.Graphics, + text, + e.Item.Font, + Rectangle.Round(rct), + color, + formatFlags); + } + else + { + var formatFlags = TextFormatFlags.WordBreak | + TextFormatFlags.EndEllipsis | + TextFormatFlags.GlyphOverhangPadding | + TextFormatFlags.NoPrefix; + + TextRenderer.DrawText( + e.Graphics, + text, + e.Item.Font, + Rectangle.Round(rct), + color, + formatFlags); + } + } + } + } + } + + public void Dispose() + { + if (this.IsDisposed) + return; + + this.UnregisterHandlers(); + this.listView.SmallImageList = null; + this.listViewImageList.Dispose(); + this.IsDisposed = true; + } + } +} diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 997f88735..277e1fee1 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -80,15 +80,6 @@ public partial class TweenMain : OTBaseForm /// プレビュー区切り位置 private int mySpDis3; - /// アイコンサイズ - /// - /// 現在は16、24、48の3種類。将来直接数字指定可能とする - /// 注:24x24の場合に26と指定しているのはMSゴシック系フォントのための仕様 - /// - private int iconSz; - - private bool iconCol; // 1列表示の時true(48サイズのとき) - // 雑多なフラグ類 private bool initial; // true:起動時処理中 private bool initialLayout = true; @@ -166,8 +157,6 @@ public partial class TweenMain : OTBaseForm private readonly ThumbnailGenerator thumbGenerator; - private readonly ImageList listViewImageList = new(); // ListViewItemの高さ変更用 - /// 発言履歴 private readonly List history = new(); @@ -191,6 +180,8 @@ public partial class TweenMain : OTBaseForm /// 発言保持クラス private readonly TabInformations statuses; + private TimelineListViewDrawer? listDrawer; + /// /// 現在表示している発言一覧の に対するキャッシュ /// @@ -304,6 +295,9 @@ public DetailsListView CurrentListView public PostClass? CurrentPost => this.CurrentTab.SelectedPost; + public bool Use2ColumnsMode + => this.settings.Common.IconSize == MyCommon.IconSizes.Icon48_2; + /// 検索処理タイプ internal enum SEARCHTYPE { @@ -348,7 +342,6 @@ protected override void Dispose(bool disposing) // 後始末 this.SearchDialog.Dispose(); this.urlDialog.Dispose(); - this.listViewImageList.Dispose(); this.themeManager.Dispose(); this.sfTab.Dispose(); @@ -374,7 +367,7 @@ private void InitColumns(ListView list, bool startup) ColumnHeader[]? columns = null; try { - if (this.iconCol) + if (this.Use2ColumnsMode) { columns = new[] { @@ -488,7 +481,7 @@ private void InitColumnText() _ => 0, }; - if (this.iconCol) + if (this.Use2ColumnsMode) { if (this.statuses.SortOrder == SortOrder.Descending) { @@ -753,7 +746,7 @@ ThumbnailGenerator thumbGenerator throw new TabException(Properties.Resources.TweenMain_LoadText1); } - this.statuses.SelectTab(this.ListTab.SelectedTab.Text); + this.ListTabSelect(this.ListTab.SelectedTab); // タブの位置を調整する this.SetTabAlignment(); @@ -2583,7 +2576,7 @@ private void MyList_ColumnClick(object sender, ColumnClickEventArgs e) /// ソートを行う ComparerMode。null であればソートを行わない private ComparerMode? GetComparerModeByColumnIndex(int columnIndex) { - if (this.iconCol) + if (this.Use2ColumnsMode) return ComparerMode.Id; return columnIndex switch @@ -2646,7 +2639,7 @@ private void SetSortColumn(ComparerMode sortColumn) this.InitColumnText(); var list = this.CurrentListView; - if (this.iconCol) + if (this.Use2ColumnsMode) { list.Columns[0].Text = this.columnText[0]; list.Columns[1].Text = this.columnText[2]; @@ -3006,7 +2999,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) { // 設定画面表示前のユーザー情報 var previousUserId = this.settings.Common.UserId; - var oldIconSz = this.settings.Common.IconSize; + var oldIconCol = this.Use2ColumnsMode; if (this.ShowSettingDialog() == DialogResult.OK) { @@ -3090,6 +3083,8 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) var newTheme = new ThemeManager(this.settings.Local); (var oldTheme, this.themeManager) = (this.themeManager, newTheme); this.tweetDetailsView.Theme = this.themeManager; + if (this.listDrawer != null) + this.listDrawer.Theme = this.themeManager; oldTheme.Dispose(); try @@ -3139,10 +3134,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) try { - var oldIconCol = this.iconCol; - - if (this.settings.Common.IconSize != oldIconSz) - this.ApplyListViewIconSize(this.settings.Common.IconSize); + this.ApplyListViewIconSize(this.settings.Common.IconSize); foreach (TabPage tp in this.ListTab.TabPages) { @@ -3154,7 +3146,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) lst.Font = this.themeManager.FontReaded; lst.BackColor = this.themeManager.ColorListBackcolor; - if (this.iconCol != oldIconCol) + if (this.Use2ColumnsMode != oldIconCol) this.ResetColumns(lst); } } @@ -3237,30 +3229,10 @@ private void SetTabAlignment() private void ApplyListViewIconSize(MyCommon.IconSizes iconSz) { // アイコンサイズの再設定 - this.iconSz = iconSz switch - { - MyCommon.IconSizes.IconNone => 0, - MyCommon.IconSizes.Icon16 => 16, - MyCommon.IconSizes.Icon24 => 26, - MyCommon.IconSizes.Icon48 => 48, - MyCommon.IconSizes.Icon48_2 => 48, - _ => throw new InvalidEnumArgumentException(nameof(iconSz), (int)iconSz, typeof(MyCommon.IconSizes)), - }; - this.iconCol = iconSz == MyCommon.IconSizes.Icon48_2; + if (this.listDrawer != null) + this.listDrawer.IconSize = iconSz; this.PurgeListViewItemCache(); - - if (this.iconSz > 0) - { - // ディスプレイの DPI 設定を考慮したサイズを設定する - this.listViewImageList.ImageSize = new Size( - 1, - (int)Math.Ceiling(this.iconSz * this.CurrentScaleFactor.Height)); - } - else - { - this.listViewImageList.ImageSize = new Size(1, 1); - } } private void ResetColumns(DetailsListView list) @@ -3558,8 +3530,6 @@ public bool AddNewTab(TabModel tab, bool startup) listCustom.GridLines = this.settings.Common.ShowGrid; listCustom.AllowDrop = true; - listCustom.SmallImageList = this.listViewImageList; - this.InitColumns(listCustom, startup); listCustom.SelectedIndexChanged += this.MyList_SelectedIndexChanged; @@ -3569,13 +3539,11 @@ public bool AddNewTab(TabModel tab, bool startup) listCustom.DragDrop += this.TweenMain_DragDrop; listCustom.DragEnter += this.TweenMain_DragEnter; listCustom.DragOver += this.TweenMain_DragOver; - listCustom.DrawItem += this.MyList_DrawItem; listCustom.MouseClick += this.MyList_MouseClick; listCustom.ColumnReordered += this.MyList_ColumnReordered; listCustom.ColumnWidthChanged += this.MyList_ColumnWidthChanged; listCustom.CacheVirtualItems += this.MyList_CacheVirtualItems; listCustom.RetrieveVirtualItem += this.MyList_RetrieveVirtualItem; - listCustom.DrawSubItem += this.MyList_DrawSubItem; listCustom.HScrolled += this.MyList_HScrolled; } @@ -3667,13 +3635,11 @@ public bool RemoveSpecifiedTab(string tabName, bool confirm) listCustom.DragDrop -= this.TweenMain_DragDrop; listCustom.DragEnter -= this.TweenMain_DragEnter; listCustom.DragOver -= this.TweenMain_DragOver; - listCustom.DrawItem -= this.MyList_DrawItem; listCustom.MouseClick -= this.MyList_MouseClick; listCustom.ColumnReordered -= this.MyList_ColumnReordered; listCustom.ColumnWidthChanged -= this.MyList_ColumnWidthChanged; listCustom.CacheVirtualItems -= this.MyList_CacheVirtualItems; listCustom.RetrieveVirtualItem -= this.MyList_RetrieveVirtualItem; - listCustom.DrawSubItem -= this.MyList_DrawSubItem; listCustom.HScrolled -= this.MyList_HScrolled; var cols = listCustom.Columns.Cast().ToList(); @@ -4318,275 +4284,6 @@ private void MyList_DrawColumnHeader(object sender, DrawListViewColumnHeaderEven private void MyList_HScrolled(object sender, EventArgs e) => ((DetailsListView)sender).Refresh(); - private void MyList_DrawItem(object sender, DrawListViewItemEventArgs e) - { - if (e.State == 0) return; - e.DrawDefault = false; - - Brush brs2; - if (!e.Item.Selected) // e.ItemStateでうまく判定できない??? - { - if (e.Item.BackColor == this.themeManager.ColorSelf) - brs2 = this.themeManager.BrushSelf; - else if (e.Item.BackColor == this.themeManager.ColorAtSelf) - brs2 = this.themeManager.BrushAtSelf; - else if (e.Item.BackColor == this.themeManager.ColorTarget) - brs2 = this.themeManager.BrushTarget; - else if (e.Item.BackColor == this.themeManager.ColorAtTarget) - brs2 = this.themeManager.BrushAtTarget; - else if (e.Item.BackColor == this.themeManager.ColorAtFromTarget) - brs2 = this.themeManager.BrushAtFromTarget; - else if (e.Item.BackColor == this.themeManager.ColorAtTo) - brs2 = this.themeManager.BrushAtTo; - else - brs2 = this.themeManager.BrushListBackcolor; - } - else - { - // 選択中の行 - if (((Control)sender).Focused) - brs2 = this.themeManager.BrushHighLight; - else - brs2 = this.themeManager.BrushDeactiveSelection; - } - e.Graphics.FillRectangle(brs2, e.Bounds); - e.DrawFocusRectangle(); - this.DrawListViewItemIcon(e); - } - - private void MyList_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) - { - if (e.ItemState == 0) return; - - if (e.ColumnIndex > 0) - { - // アイコン以外の列 - var post = (PostClass)e.Item.Tag; - - RectangleF rct = e.Bounds; - rct.Width = e.Header.Width; - var fontHeight = e.Item.Font.Height; - if (this.iconCol) - { - rct.Y += fontHeight; - rct.Height -= fontHeight; - } - - var drawLineCount = Math.Max(1, Math.DivRem((int)rct.Height, fontHeight, out var heightDiff)); - - // フォントの高さの半分を足してるのは保険。無くてもいいかも。 - if (this.iconCol || drawLineCount > 1) - { - if (heightDiff < fontHeight * 0.7) - { - // 最終行が70%以上欠けていたら、最終行は表示しない - rct.Height = (fontHeight * drawLineCount) - 1; - } - else - { - drawLineCount += 1; - } - } - - if (rct.Width > 0) - { - var color = (!e.Item.Selected) ? e.Item.ForeColor : // 選択されていない行 - ((Control)sender).Focused ? this.themeManager.ColorHighLight : // 選択中の行 - this.themeManager.ColorUnread; - - if (this.iconCol) - { - var rctB = e.Bounds; - rctB.Width = e.Header.Width; - rctB.Height = fontHeight; - - Font fontBold; - if (e.Item.Font.Equals(this.themeManager.FontUnread)) - fontBold = this.themeManager.FontUnreadBold; - else - fontBold = this.themeManager.FontReadedBold; - - var formatFlags1 = TextFormatFlags.WordBreak | - TextFormatFlags.EndEllipsis | - TextFormatFlags.GlyphOverhangPadding | - TextFormatFlags.NoPrefix; - - TextRenderer.DrawText( - e.Graphics, - post.IsDeleted ? "(DELETED)" : post.TextSingleLine, - e.Item.Font, - Rectangle.Round(rct), - color, - formatFlags1); - - var formatFlags2 = TextFormatFlags.SingleLine | - TextFormatFlags.EndEllipsis | - TextFormatFlags.GlyphOverhangPadding | - TextFormatFlags.NoPrefix; - - TextRenderer.DrawText( - e.Graphics, - e.Item.SubItems[4].Text + " / " + e.Item.SubItems[1].Text + " (" + e.Item.SubItems[3].Text + ") " + e.Item.SubItems[5].Text + e.Item.SubItems[6].Text + " [" + e.Item.SubItems[7].Text + "]", - fontBold, - rctB, - color, - formatFlags2); - } - else - { - string text; - if (e.ColumnIndex != 2) - text = e.SubItem.Text; - else - text = post.IsDeleted ? "(DELETED)" : post.TextSingleLine; - - if (drawLineCount == 1) - { - var formatFlags = TextFormatFlags.SingleLine | - TextFormatFlags.EndEllipsis | - TextFormatFlags.GlyphOverhangPadding | - TextFormatFlags.NoPrefix | - TextFormatFlags.VerticalCenter; - - TextRenderer.DrawText( - e.Graphics, - text, - e.Item.Font, - Rectangle.Round(rct), - color, - formatFlags); - } - else - { - var formatFlags = TextFormatFlags.WordBreak | - TextFormatFlags.EndEllipsis | - TextFormatFlags.GlyphOverhangPadding | - TextFormatFlags.NoPrefix; - - TextRenderer.DrawText( - e.Graphics, - text, - e.Item.Font, - Rectangle.Round(rct), - color, - formatFlags); - } - } - } - } - } - - private void DrawListViewItemIcon(DrawListViewItemEventArgs e) - { - if (this.iconSz == 0) return; - - var item = e.Item; - - // e.Bounds.Leftが常に0を指すから自前で計算 - var itemRect = item.Bounds; - var col0 = e.Item.ListView.Columns[0]; - itemRect.Width = col0.Width; - - if (col0.DisplayIndex > 0) - { - foreach (ColumnHeader clm in e.Item.ListView.Columns) - { - if (clm.DisplayIndex < col0.DisplayIndex) - itemRect.X += clm.Width; - } - } - - // ディスプレイの DPI 設定を考慮したアイコンサイズ - var realIconSize = new SizeF(this.iconSz * this.CurrentScaleFactor.Width, this.iconSz * this.CurrentScaleFactor.Height).ToSize(); - var realStateSize = new SizeF(16 * this.CurrentScaleFactor.Width, 16 * this.CurrentScaleFactor.Height).ToSize(); - - var iconRect = Rectangle.Intersect(new Rectangle(e.Item.GetBounds(ItemBoundsPortion.Icon).Location, realIconSize), itemRect); - iconRect.Offset(0, Math.Max(0, (itemRect.Height - realIconSize.Height) / 2)); - - var post = this.CurrentTab[item.Index]; - var img = this.LoadListViewIconLazy(item.ListView, post, realIconSize.Width); - if (img != null) - { - e.Graphics.FillRectangle(Brushes.White, iconRect); - e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; - try - { - e.Graphics.DrawImage(img.Image, iconRect); - } - catch (ArgumentException) - { - } - } - - if (post.StateIndex > -1) - { - var stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + realIconSize.Width + 2, iconRect.Y), realStateSize), itemRect); - if (stateRect.Width > 0) - e.Graphics.DrawIcon(this.GetPostStateIcon(post.StateIndex), stateRect); - } - } - - private MemoryImage? LoadListViewIconLazy(ListView listView, PostClass post, int scaledIconSize) - { - if (scaledIconSize <= 0) - return null; - - var normalImageUrl = post.ImageUrl; - if (MyCommon.IsNullOrEmpty(normalImageUrl)) - return null; - - var sizeName = Twitter.DecideProfileImageSize(scaledIconSize); - var cachedImage = this.iconCache.TryGetLargerOrSameSizeFromCache(normalImageUrl, sizeName); - if (cachedImage != null) - return cachedImage; - - // キャッシュにない画像の場合は読み込みが完了してから再描画する - _ = Task.Run(async () => - { - var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); - var image = await this.iconCache.DownloadImageAsync(imageUrl); - - await this.InvokeAsync(() => - { - if (listView.IsDisposed) - return; - - if (listView != this.CurrentListView) - return; - - // ロード中に index の指す行が変化している可能性がある - var newIndex = this.CurrentTab.IndexOf(post.StatusId); - if (newIndex != -1) - listView.RedrawItems(newIndex, newIndex, true); - }); - }); - - return null; - } - - private Icon GetPostStateIcon(int stateIndex) - { - return stateIndex switch - { - 0 => Properties.Resources.PostState00, - 1 => Properties.Resources.PostState01, - 2 => Properties.Resources.PostState02, - 3 => Properties.Resources.PostState03, - 4 => Properties.Resources.PostState04, - 5 => Properties.Resources.PostState05, - 6 => Properties.Resources.PostState06, - 7 => Properties.Resources.PostState07, - 8 => Properties.Resources.PostState08, - 9 => Properties.Resources.PostState09, - 10 => Properties.Resources.PostState10, - 11 => Properties.Resources.PostState11, - 12 => Properties.Resources.PostState12, - 13 => Properties.Resources.PostState13, - 14 => Properties.Resources.PostState14, - _ => throw new IndexOutOfRangeException(), - }; - } - protected override void ScaleControl(SizeF factor, BoundsSpecified specified) { base.ScaleControl(factor, specified); @@ -4880,8 +4577,9 @@ private void JumpUnreadMenuItem_Click(object sender, EventArgs e) if (this.statuses.SortMode == ComparerMode.Id) { - if (this.statuses.SortOrder == SortOrder.Ascending && lst.Items[foundIndex].Position.Y > lst.ClientSize.Height - this.iconSz - 10 || - this.statuses.SortOrder == SortOrder.Descending && lst.Items[foundIndex].Position.Y < this.iconSz + 10) + var rowHeight = lst.SmallImageList.ImageSize.Height; + if (this.statuses.SortOrder == SortOrder.Ascending && lst.Items[foundIndex].Position.Y > lst.ClientSize.Height - rowHeight - 10 || + this.statuses.SortOrder == SortOrder.Descending && lst.Items[foundIndex].Position.Y < rowHeight + 10) { this.MoveTop(); } @@ -8493,7 +8191,7 @@ private void MenuStrip1_MenuDeactivate(object sender, EventArgs e) private void MyList_ColumnReordered(object sender, ColumnReorderedEventArgs e) { - if (this.iconCol) + if (this.Use2ColumnsMode) { e.Cancel = true; return; @@ -8521,7 +8219,7 @@ private void MyList_ColumnWidthChanged(object sender, ColumnWidthChangedEventArg if (this.settings.Local == null) return; var modified = false; - if (this.iconCol) + if (this.Use2ColumnsMode) { if (this.settings.Local.ColumnsWidth[0] != lst.Columns[0].Width) { @@ -8744,19 +8442,20 @@ private async Task OpenInternalUriAsync(Uri uri) } } - private void ListTabSelect(TabPage tab) + private void ListTabSelect(TabPage tabPage) { this.SetListProperty(); this.PurgeListViewItemCache(); - this.statuses.SelectTab(tab.Text); + this.statuses.SelectTab(tabPage.Text); var listView = this.CurrentListView; + this.InitializeTimelineListView(); this.CurrentTab.ClearAnchor(); - if (this.iconCol) + if (this.Use2ColumnsMode) { listView.Columns[1].Text = this.columnText[2]; } @@ -8769,6 +8468,19 @@ private void ListTabSelect(TabPage tab) } } + private void InitializeTimelineListView() + { + var listView = this.CurrentListView; + var tab = this.CurrentTab; + + var newDrawer = new TimelineListViewDrawer(listView, tab, this.iconCache, this.themeManager) + { + IconSize = this.settings.Common.IconSize, + }; + (this.listDrawer, var oldDrawer) = (newDrawer, this.listDrawer); + oldDrawer?.Dispose(); + } + private void ListTab_Selecting(object sender, TabControlCancelEventArgs e) => this.ListTabSelect(e.TabPage); @@ -10475,12 +10187,12 @@ private void ChangeListViewIconSize(MyCommon.IconSizes iconSize) { if (this.settings.Common.IconSize == iconSize) return; - var oldIconCol = this.iconCol; + var oldIconCol = this.Use2ColumnsMode; this.settings.Common.IconSize = iconSize; this.ApplyListViewIconSize(iconSize); - if (this.iconCol != oldIconCol) + if (this.Use2ColumnsMode != oldIconCol) { foreach (TabPage tp in this.ListTab.TabPages) { From 375dd262a46d778aa2ce12ef6d0176a300541f6a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Apr 2022 05:22:24 +0900 Subject: [PATCH 185/402] =?UTF-8?q?=E9=9D=9E=E3=82=A2=E3=82=AF=E3=83=86?= =?UTF-8?q?=E3=82=A3=E3=83=96=E3=81=AA=E3=82=BF=E3=83=96=E3=81=AEListView?= =?UTF-8?q?=E3=82=92=E7=A9=BA=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/TabModelTest.cs | 2 + OpenTween/Models/TabModel.cs | 3 + OpenTween/TimelineListViewDrawer.cs | 3 + OpenTween/Tween.cs | 128 ++++++++++--------------- 4 files changed, 56 insertions(+), 80 deletions(-) diff --git a/OpenTween.Tests/Models/TabModelTest.cs b/OpenTween.Tests/Models/TabModelTest.cs index 2cf139d1a..518334216 100644 --- a/OpenTween.Tests/Models/TabModelTest.cs +++ b/OpenTween.Tests/Models/TabModelTest.cs @@ -117,6 +117,7 @@ public void SelectPosts_Test() Assert.Equal(new[] { posts[0], posts[2] }, tab.SelectedPosts); Assert.Equal(posts[0], tab.SelectedPost); Assert.Equal(0, tab.SelectedIndex); + Assert.Equal(new[] { 0, 2 }, tab.SelectedIndices); } [Fact] @@ -133,6 +134,7 @@ public void SelectPosts_EmptyTest() Assert.Empty(tab.SelectedPosts); Assert.Null(tab.SelectedPost); Assert.Equal(-1, tab.SelectedIndex); + Assert.Empty(tab.SelectedIndices); } [Fact] diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index d9c054279..cd6575eb5 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -100,6 +100,9 @@ public int SelectedIndex } } + public int[] SelectedIndices + => this.SelectedPosts.Select(x => this.IndexOf(x.StatusId)).Where(x => x != -1).ToArray(); + public long? AnchorStatusId { get; set; } public PostClass? AnchorPost diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs index 176b222c9..389b123bd 100644 --- a/OpenTween/TimelineListViewDrawer.cs +++ b/OpenTween/TimelineListViewDrawer.cs @@ -183,6 +183,9 @@ await this.listView.InvokeAsync(() => if (this.listView.IsDisposed) return; + if (this.listView.VirtualListSize == 0) + return; + // ロード中に index の指す行が変化している可能性がある var newIndex = this.tab.IndexOf(post.StatusId); if (newIndex != -1) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 277e1fee1..60b2d5cbb 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -954,33 +954,26 @@ private void RefreshTimeline() if (MyCommon.EndingFlag) return; // リストに反映&選択状態復元 - foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) + if (curListView.VirtualListSize != curTabModel.AllCount || isDelete) { - var tabPage = this.ListTab.TabPages[index]; - var listView = (DetailsListView)tabPage.Tag; - - if (listView.VirtualListSize != tab.AllCount || isDelete) + using (ControlTransaction.Update(curListView)) { - using (ControlTransaction.Update(listView)) - { - if (listView == curListView) - this.PurgeListViewItemCache(); - - try - { - // リスト件数更新 - listView.VirtualListSize = tab.AllCount; - } - catch (NullReferenceException ex) - { - // WinForms 内部で ListView.set_TopItem が発生させている例外 - // https://ja.osdn.net/ticket/browse.php?group_id=6526&tid=36588 - MyCommon.TraceOut(ex, $"TabType: {tab.TabType}, Count: {tab.AllCount}, ListSize: {listView.VirtualListSize}"); - } + this.PurgeListViewItemCache(); - // 選択位置などを復元 - this.RestoreListViewSelection(listView, tab, listSelections[tab.TabName]); + try + { + // リスト件数更新 + curListView.VirtualListSize = curTabModel.AllCount; + } + catch (NullReferenceException ex) + { + // WinForms 内部で ListView.set_TopItem が発生させている例外 + // https://ja.osdn.net/ticket/browse.php?group_id=6526&tid=36588 + MyCommon.TraceOut(ex, $"TabType: {curTabModel.TabType}, Count: {curTabModel.AllCount}, ListSize: {curListView.VirtualListSize}"); } + + // 選択位置などを復元 + this.RestoreListViewSelection(curListView, curTabModel, listSelections[curTabModel.TabName]); } } @@ -2858,34 +2851,29 @@ await this.tw.Api.StatusesDestroy(post.StatusId) this.PurgeListViewItemCache(); - foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) + using (ControlTransaction.Update(currentListView)) { - var tabPage = this.ListTab.TabPages[index]; - var listView = (DetailsListView)tabPage.Tag; + var currentTab = this.CurrentTab; + currentListView.VirtualListSize = currentTab.AllCount; + currentListView.SelectedIndices.Clear(); - using (ControlTransaction.Update(listView)) + if (currentTab.AllCount != 0) { - listView.VirtualListSize = tab.AllCount; - - if (tab.TabName == this.CurrentTabName) - { - listView.SelectedIndices.Clear(); - - if (tab.AllCount != 0) - { - int selectedIndex; - if (tab.AllCount - 1 > focusedIndex && focusedIndex > -1) - selectedIndex = focusedIndex; - else - selectedIndex = tab.AllCount - 1; + int selectedIndex; + if (currentTab.AllCount - 1 > focusedIndex && focusedIndex > -1) + selectedIndex = focusedIndex; + else + selectedIndex = currentTab.AllCount - 1; - listView.SelectedIndices.Add(selectedIndex); - listView.EnsureVisible(selectedIndex); - listView.FocusedItem = listView.Items[selectedIndex]; - } - } + currentListView.SelectedIndices.Add(selectedIndex); + currentListView.EnsureVisible(selectedIndex); + currentListView.FocusedItem = currentListView.Items[selectedIndex]; } + } + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) + { + var tabPage = this.ListTab.TabPages[index]; if (this.settings.Common.TabIconDisp && tab.UnreadCount == 0) { if (tabPage.ImageIndex == 0) @@ -3662,12 +3650,6 @@ public bool RemoveSpecifiedTab(string tabName, bool confirm) listCustom.Dispose(); this.statuses.RemoveTab(tabName); - foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) - { - var lst = (DetailsListView)this.ListTab.TabPages[index].Tag; - lst.VirtualListSize = tab.AllCount; - } - return true; } @@ -4252,14 +4234,13 @@ private void ApplyPostFilters() this.PurgeListViewItemCache(); this.statuses.FilterAll(); + var listView = this.CurrentListView; + using (ControlTransaction.Update(listView)) + listView.VirtualListSize = this.CurrentTab.AllCount; + foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { var tabPage = this.ListTab.TabPages[index]; - var listview = (DetailsListView)tabPage.Tag; - using (ControlTransaction.Update(listview)) - { - listview.VirtualListSize = tab.AllCount; - } if (this.settings.Common.TabIconDisp) { @@ -7465,15 +7446,13 @@ private void ClearTab(string tabName, bool showWarning) { this.CurrentTab.ClearAnchor(); this.PurgeListViewItemCache(); + this.CurrentListView.VirtualListSize = 0; } var tabIndex = this.statuses.Tabs.IndexOf(tabName); var tabPage = this.ListTab.TabPages[tabIndex]; tabPage.ImageIndex = -1; - var listView = (DetailsListView)tabPage.Tag; - listView.VirtualListSize = 0; - if (!this.settings.Common.TabIconDisp) this.ListTab.Refresh(); this.SetMainWindowTitle(); @@ -8446,14 +8425,21 @@ private void ListTabSelect(TabPage tabPage) { this.SetListProperty(); + if (!MyCommon.IsNullOrEmpty(this.statuses.SelectedTabName)) + this.CurrentListView.VirtualListSize = 0; + this.PurgeListViewItemCache(); this.statuses.SelectTab(tabPage.Text); - var listView = this.CurrentListView; - this.InitializeTimelineListView(); - this.CurrentTab.ClearAnchor(); + + var tab = this.CurrentTab; + tab.ClearAnchor(); + + var listView = this.CurrentListView; + listView.VirtualListSize = tab.AllCount; + listView.SelectItems(tab.SelectedIndices); if (this.Use2ColumnsMode) { @@ -9256,8 +9242,6 @@ private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) } else { - DetailsListView? listView; - var tb = this.statuses.RemovedTab.Pop(); if (tb.TabType == MyCommon.TabUsageType.Related) { @@ -9271,8 +9255,6 @@ private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) this.statuses.ReplaceTab(tb); var tabIndex = this.statuses.Tabs.IndexOf(tb); - var tabPage = this.ListTab.TabPages[tabIndex]; - listView = (DetailsListView)tabPage.Tag; this.ListTab.SelectedIndex = tabIndex; } else @@ -9291,9 +9273,6 @@ private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) this.AddNewTab(tb, startup: false); var tabIndex = this.statuses.Tabs.Count - 1; - var tabPage = this.ListTab.TabPages[tabIndex]; - - listView = (DetailsListView)tabPage.Tag; this.ListTab.SelectedIndex = tabIndex; } } @@ -9312,20 +9291,9 @@ private void UndoRemoveTabMenuItem_Click(object sender, EventArgs e) this.AddNewTab(tb, startup: false); var tabIndex = this.statuses.Tabs.Count - 1; - var tabPage = this.ListTab.TabPages[tabIndex]; - - listView = (DetailsListView)tabPage.Tag; this.ListTab.SelectedIndex = tabIndex; } this.SaveConfigsTabs(); - - if (listView != null) - { - using (ControlTransaction.Update(listView)) - { - listView.VirtualListSize = tb.AllCount; - } - } } } From d5d2f848c743c878b062e13e07be8e5f0abbb50a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Apr 2022 19:59:09 +0900 Subject: [PATCH 186/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AEVirtualMode=E3=81=AB=E9=96=A2=E3=81=99=E3=82=8B?= =?UTF-8?q?=E5=AE=9F=E8=A3=85=E3=82=92TimelineListViewCache=E3=82=AF?= =?UTF-8?q?=E3=83=A9=E3=82=B9=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/ListViewItemCacheTest.cs | 96 +++++ OpenTween.Tests/TestUtils.cs | 3 + OpenTween.Tests/TimelineListViewCacheTest.cs | 408 ++++++++++++++++++ OpenTween/OpenTween.csproj | 1 + OpenTween/TimelineListViewCache.cs | 430 +++++++++++++++++++ OpenTween/Tween.cs | 422 ++---------------- 6 files changed, 977 insertions(+), 383 deletions(-) create mode 100644 OpenTween.Tests/ListViewItemCacheTest.cs create mode 100644 OpenTween.Tests/TimelineListViewCacheTest.cs create mode 100644 OpenTween/TimelineListViewCache.cs diff --git a/OpenTween.Tests/ListViewItemCacheTest.cs b/OpenTween.Tests/ListViewItemCacheTest.cs new file mode 100644 index 000000000..4c7018060 --- /dev/null +++ b/OpenTween.Tests/ListViewItemCacheTest.cs @@ -0,0 +1,96 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Windows.Forms; +using OpenTween.Models; +using Xunit; + +namespace OpenTween +{ + public class ListViewItemCacheTest + { + [Fact] + public void Cache_InvalidSizeTest() + { + var startIndex = 10; + var endIndex = 19; + Assert.Throws( + () => new ListViewItemCache(startIndex, endIndex, new (ListViewItem, PostClass)[9]) + ); + Assert.Throws( + () => new ListViewItemCache(startIndex, endIndex, new (ListViewItem, PostClass)[11]) + ); + } + + [Fact] + public void Count_Test() + { + var cache = new ListViewItemCache(10, 19, new (ListViewItem, PostClass)[10]); + Assert.Equal(10, cache.Count); + } + + [Theory] + [InlineData(9, false)] + [InlineData(10, true)] + [InlineData(19, true)] + [InlineData(20, false)] + public void Contains_Test(int index, bool expected) + { + var cache = new ListViewItemCache(10, 19, new (ListViewItem, PostClass)[10]); + Assert.Equal(expected, cache.Contains(index)); + } + + [Theory] + [InlineData(9, 19, false)] + [InlineData(9, 20, false)] + [InlineData(10, 19, true)] + [InlineData(10, 20, false)] + public void IsSupersetOf_Test(int start, int end, bool expected) + { + var cache = new ListViewItemCache(10, 19, new (ListViewItem, PostClass)[10]); + Assert.Equal(expected, cache.IsSupersetOf(start, end)); + } + + [Fact] + public void TryGetValue_FoundTest() + { + var item = new ListViewItem(); + var post = new PostClass(); + var cache = new ListViewItemCache(10, 10, new[] { (item, post) }); + + Assert.True(cache.TryGetValue(10, out var actualItem, out var actualPost)); + Assert.Equal(item, actualItem); + Assert.Equal(post, actualPost); + } + + [Fact] + public void TryGetValue_NotFoundTest() + { + var item = new ListViewItem(); + var post = new PostClass(); + var cache = new ListViewItemCache(10, 10, new[] { (item, post) }); + + Assert.False(cache.TryGetValue(9, out _, out _)); + Assert.False(cache.TryGetValue(11, out _, out _)); + } + } +} diff --git a/OpenTween.Tests/TestUtils.cs b/OpenTween.Tests/TestUtils.cs index d7e2fb227..e7fe87b8a 100644 --- a/OpenTween.Tests/TestUtils.cs +++ b/OpenTween.Tests/TestUtils.cs @@ -149,6 +149,9 @@ private sealed class RestoreFreezedTime : IDisposable public void Dispose() => DateTimeUtc.UseFakeNow = false; } + + public static DateTimeUtc LocalTime(int year, int month, int day, int hour, int minute, int second) + => new(new DateTimeOffset(year, month, day, hour, minute, second, TimeZoneInfo.Local.BaseUtcOffset)); } } diff --git a/OpenTween.Tests/TimelineListViewCacheTest.cs b/OpenTween.Tests/TimelineListViewCacheTest.cs new file mode 100644 index 000000000..a63bee002 --- /dev/null +++ b/OpenTween.Tests/TimelineListViewCacheTest.cs @@ -0,0 +1,408 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using OpenTween.Models; +using OpenTween.OpenTweenCustomControl; +using Xunit; + +namespace OpenTween +{ + public class TimelineListViewCacheTest + { + private readonly Random random = new(); + + private PostClass CreatePost() + { + return new() + { + StatusId = this.random.Next(10000), + UserId = this.random.Next(10000), + ScreenName = "test", + Nickname = "てすと", + AccessibleText = "foo", + Source = "OpenTween", + FavoritedCount = 0, + CreatedAt = TestUtils.LocalTime(2022, 1, 1, 0, 0, 0), + IsRead = true, + }; + } + + [Fact] + public void UpdateListSize_Test() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + Assert.Equal(0, listView.VirtualListSize); + Assert.False(cache.IsListSizeMismatched); + + tab.AddPostQueue(this.CreatePost()); + tab.AddSubmit(); + + Assert.True(cache.IsListSizeMismatched); + + cache.UpdateListSize(); + + Assert.Equal(1, listView.VirtualListSize); + Assert.False(cache.IsListSizeMismatched); + } + + [Fact] + public void CreateItem_Test() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + var item = cache.CreateItem(post); + + Assert.Equal("", item.SubItems[0].Text); + Assert.Equal("てすと", item.SubItems[1].Text); + Assert.Equal("foo", item.SubItems[2].Text); + Assert.Equal("2022/01/01 0:00:00", item.SubItems[3].Text); + Assert.Equal("test", item.SubItems[4].Text); + Assert.Equal("", item.SubItems[5].Text); + Assert.Equal("", item.SubItems[6].Text); + Assert.Equal("OpenTween", item.SubItems[7].Text); + } + + [Fact] + public void CreateItem_UnreadTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.IsRead = false; + + var item = cache.CreateItem(post); + Assert.Equal("★", item.SubItems[5].Text); + } + + [Fact] + public void CreateItem_FavoritesTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.FavoritedCount = 1; + + var item = cache.CreateItem(post); + Assert.Equal("+1", item.SubItems[6].Text); + } + + [Fact] + public void CreateItem_RetweetTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.RetweetedId = 50L; + post.RetweetedBy = "hoge"; + + var item = cache.CreateItem(post); + Assert.Equal($"test{Environment.NewLine}(RT:hoge)", item.SubItems[4].Text); + } + + [Fact] + public void CreateItem_DeletedTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.IsDeleted = true; + + var item = cache.CreateItem(post); + Assert.Equal("(DELETED)", item.SubItems[2].Text); + } + + [Fact] + public void CreateItem_Font_ReadedTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.IsRead = true; + + var item = cache.CreateItem(post); + Assert.Equal(theme.FontReaded, item.Font); + } + + [Fact] + public void CreateItem_Font_UnreadTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.IsRead = false; + + var item = cache.CreateItem(post); + Assert.Equal(theme.FontUnread, item.Font); + } + + [Fact] + public void CreateItem_Font_UnreadStyleDisabledTest() + { + var tab = new PublicSearchTabModel("tab"); + var settingCommon = new SettingCommon(); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, settingCommon, theme); + + var post = this.CreatePost(); + post.IsRead = false; + + settingCommon.UseUnreadStyle = false; + + var item = cache.CreateItem(post); + Assert.Equal(theme.FontReaded, item.Font); + } + + [Fact] + public void CreateItem_ForeColor_Test() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + + var item = cache.CreateItem(post); + Assert.Equal(theme.ColorRead, item.ForeColor); + } + + [Fact] + public void CreateItem_ForeColor_FavoritedTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.IsFav = true; + + var item = cache.CreateItem(post); + Assert.Equal(theme.ColorFav, item.ForeColor); + } + + [Fact] + public void CreateItem_ForeColor_RetweetTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.RetweetedId = 100L; + + var item = cache.CreateItem(post); + Assert.Equal(theme.ColorRetweet, item.ForeColor); + } + + [Fact] + public void CreateItem_ForeColor_OWLTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.IsOwl = true; + + var item = cache.CreateItem(post); + Assert.Equal(theme.ColorOWL, item.ForeColor); + } + + [Fact] + public void CreateItem_ForeColor_OWLStyleDisabledTest() + { + var tab = new PublicSearchTabModel("tab"); + var settingCommon = new SettingCommon(); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, settingCommon, theme); + + var post = this.CreatePost(); + post.IsOwl = true; + + settingCommon.OneWayLove = false; + + var item = cache.CreateItem(post); + Assert.Equal(theme.ColorRead, item.ForeColor); + } + + [Fact] + public void CreateItem_ForeColor_DMTest() + { + var tab = new PublicSearchTabModel("tab"); + var settingCommon = new SettingCommon(); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, settingCommon, theme); + + var post = this.CreatePost(); + post.IsDm = true; + post.IsOwl = true; + + // DM の場合は設定に関わらず ColorOWL を使う + settingCommon.OneWayLove = false; + + var item = cache.CreateItem(post); + Assert.Equal(theme.ColorOWL, item.ForeColor); + } + + [Fact] + public void JudgeColor_AtToTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var targetPost = this.CreatePost(); + + var basePost = this.CreatePost(); + basePost.InReplyToStatusId = targetPost.StatusId; + + Assert.Equal(theme.ColorAtTo, cache.JudgeColor(basePost, targetPost)); + } + + [Fact] + public void JudgeColor_SelfTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var targetPost = this.CreatePost(); + targetPost.IsMe = true; + + var basePost = this.CreatePost(); + + Assert.Equal(theme.ColorSelf, cache.JudgeColor(basePost, targetPost)); + } + + [Fact] + public void JudgeColor_AtSelfTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var targetPost = this.CreatePost(); + targetPost.IsReply = true; + + var basePost = this.CreatePost(); + + Assert.Equal(theme.ColorAtSelf, cache.JudgeColor(basePost, targetPost)); + } + + [Fact] + public void JudgeColor_AtFromTargetTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var targetPost = this.CreatePost(); + + var basePost = this.CreatePost(); + basePost.ReplyToList = new() { (targetPost.UserId, targetPost.ScreenName) }; + + Assert.Equal(theme.ColorAtFromTarget, cache.JudgeColor(basePost, targetPost)); + } + + [Fact] + public void JudgeColor_AtTargetTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var basePost = this.CreatePost(); + + var targetPost = this.CreatePost(); + targetPost.ReplyToList = new() { (basePost.UserId, basePost.ScreenName) }; + + Assert.Equal(theme.ColorAtTarget, cache.JudgeColor(basePost, targetPost)); + } + + [Fact] + public void JudgeColor_TargetTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var targetPost = this.CreatePost(); + + var basePost = this.CreatePost(); + basePost.UserId = targetPost.UserId; + + Assert.Equal(theme.ColorTarget, cache.JudgeColor(basePost, targetPost)); + } + + [Fact] + public void JudgeColor_NormalTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var targetPost = this.CreatePost(); + var basePost = this.CreatePost(); + + Assert.Equal(theme.ColorListBackcolor, cache.JudgeColor(basePost, targetPost)); + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index dba7afc86..33bb4ea46 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -202,6 +202,7 @@ + diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs new file mode 100644 index 000000000..ae1be743a --- /dev/null +++ b/OpenTween/TimelineListViewCache.cs @@ -0,0 +1,430 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) +// (c) 2008-2011 Moz (@syo68k) +// (c) 2008-2011 takeshik (@takeshik) +// (c) 2010-2011 anis774 (@anis774) +// (c) 2010-2011 fantasticswallow (@f_swallow) +// (c) 2011 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading; +using System.Windows.Forms; +using OpenTween.Models; +using OpenTween.OpenTweenCustomControl; + +namespace OpenTween +{ + public sealed class TimelineListViewCache : IDisposable + { + public bool IsDisposed { get; private set; } = false; + + public ThemeManager Theme { get; set; } + + public bool IsListSizeMismatched + => this.listView.VirtualListSize != this.tab.AllCount; + + private readonly DetailsListView listView; + private readonly TabModel tab; + private readonly SettingCommon settings; + + /// + /// 現在表示している発言一覧の に対するキャッシュ + /// + /// + /// キャッシュクリアのために null が代入されることがあるため、 + /// 使用する場合には に対して直接メソッド等を呼び出さずに + /// 一旦ローカル変数に代入してから参照すること。 + /// + private ListViewItemCache? listItemCache = null; + + public TimelineListViewCache( + DetailsListView listView, + TabModel tab, + SettingCommon settings, + ThemeManager theme + ) + { + this.listView = listView; + this.tab = tab; + this.settings = settings; + this.Theme = theme; + + this.RegisterHandlers(); + this.listView.VirtualMode = true; + this.UpdateListSize(); + } + + private void RegisterHandlers() + { + this.listView.CacheVirtualItems += this.ListView_CacheVirtualItems; + this.listView.RetrieveVirtualItem += this.ListView_RetrieveVirtualItem; + } + + private void UnregisterHandlers() + { + this.listView.CacheVirtualItems -= this.ListView_CacheVirtualItems; + this.listView.RetrieveVirtualItem -= this.ListView_RetrieveVirtualItem; + } + + public void UpdateListSize() + { + try + { + // リスト件数更新 + this.listView.VirtualListSize = this.tab.AllCount; + } + catch (NullReferenceException ex) + { + // WinForms 内部で ListView.set_TopItem が発生させている例外 + // https://ja.osdn.net/ticket/browse.php?group_id=6526&tid=36588 + MyCommon.TraceOut(ex, $"TabType: {this.tab.TabType}, Count: {this.tab.AllCount}, ListSize: {this.listView.VirtualListSize}"); + } + } + + private void CreateCache(int startIndex, int endIndex) + { + if (this.tab.AllCount == 0) + return; + + // インデックスを 0...(tabInfo.AllCount - 1) の範囲内にする + int FilterRange(int index) + => Math.Max(Math.Min(index, this.tab.AllCount - 1), 0); + + // キャッシュ要求(要求範囲±30を作成) + startIndex = FilterRange(startIndex - 30); + endIndex = FilterRange(endIndex + 30); + + var cacheLength = endIndex - startIndex + 1; + + var posts = this.tab[startIndex, endIndex]; // 配列で取得 + var listItems = Enumerable.Range(0, cacheLength) + .Select(x => this.CreateItem(posts[x])) + .ToArray(); + + var listCache = new ListViewItemCache( + startIndex, + endIndex, + Enumerable.Zip(listItems, posts, (x, y) => (x, y)).ToArray() + ); + + Interlocked.Exchange(ref this.listItemCache, listCache); + } + + /// + /// DetailsListView のための ListViewItem のキャッシュを消去する + /// + public void PurgeCache() + => Interlocked.Exchange(ref this.listItemCache, null); + + internal ListViewItem CreateItem(PostClass post) + { + var mk = new StringBuilder(); + + if (post.FavoritedCount > 0) mk.Append("+" + post.FavoritedCount); + + ListViewItem itm; + if (post.RetweetedId == null) + { + string[] sitem = + { + "", + post.Nickname, + post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), + post.CreatedAt.ToLocalTimeString(this.settings.DateTimeFormat), + post.ScreenName, + "", + mk.ToString(), + post.Source, + }; + itm = new ListViewItem(sitem); + } + else + { + string[] sitem = + { + "", + post.Nickname, + post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), + post.CreatedAt.ToLocalTimeString(this.settings.DateTimeFormat), + post.ScreenName + Environment.NewLine + "(RT:" + post.RetweetedBy + ")", + "", + mk.ToString(), + post.Source, + }; + itm = new ListViewItem(sitem); + } + itm.Tag = post; + + var read = post.IsRead; + // 未読管理していなかったら既読として扱う + if (!this.tab.UnreadManage || !this.settings.UnreadManage) + read = true; + + this.ChangeItemStyleRead(read, itm, post); + this.ColorizeList(itm, post); + + return itm; + } + + public void ChangeCacheStyleRead(bool read, int index) + { + // Read:true=既読 false=未読 + // 未読管理していなかったら既読として扱う + if (!this.tab.UnreadManage || + !this.settings.UnreadManage) read = true; + + var listCache = this.listItemCache; + if (listCache == null) + return; + + // キャッシュに含まれていないアイテムは対象外 + if (!listCache.TryGetValue(index, out var itm, out var post)) + return; + + this.ChangeItemStyleRead(read, itm, post); + } + + private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post) + { + Font fnt; + string star; + // フォント + if (read) + { + fnt = this.Theme.FontReaded; + star = ""; + } + else + { + fnt = this.Theme.FontUnread; + star = "★"; + } + if (item.SubItems[5].Text != star) + item.SubItems[5].Text = star; + + // 文字色 + Color cl; + if (post.IsFav) + cl = this.Theme.ColorFav; + else if (post.RetweetedId != null) + cl = this.Theme.ColorRetweet; + else if (post.IsOwl && (post.IsDm || this.settings.OneWayLove)) + cl = this.Theme.ColorOWL; + else if (read || !this.settings.UseUnreadStyle) + cl = this.Theme.ColorRead; + else + cl = this.Theme.ColorUnread; + + if (item.Index == -1) + { + item.ForeColor = cl; + if (this.settings.UseUnreadStyle) + item.Font = fnt; + } + else + { + this.listView.Update(); + if (this.settings.UseUnreadStyle) + this.listView.ChangeItemFontAndColor(item, cl, fnt); + else + this.listView.ChangeItemForeColor(item, cl); + } + } + + public void ColorizeList() + { + // Index:更新対象のListviewItem.Index。Colorを返す。 + // -1は全キャッシュ。Colorは返さない(ダミーを戻す) + var post = this.tab.AnchorPost ?? this.tab.SelectedPost; + if (post == null) + return; + + var listCache = this.listItemCache; + if (listCache == null) + return; + + // ValidateRectが呼ばれる前に選択色などの描画を済ませておく + this.listView.Update(); + + foreach (var (listViewItem, cachedPost) in listCache.Cache) + { + var backColor = this.JudgeColor(post, cachedPost); + this.listView.ChangeItemBackColor(listViewItem, backColor); + } + } + + private void ColorizeList(ListViewItem item, PostClass post) + { + // Index:更新対象のListviewItem.Index。Colorを返す。 + // -1は全キャッシュ。Colorは返さない(ダミーを戻す) + var basePost = this.tab.AnchorPost ?? this.tab.SelectedPost; + if (basePost == null) + return; + + if (item.Index == -1) + item.BackColor = this.JudgeColor(basePost, post); + else + this.listView.ChangeItemBackColor(item, this.JudgeColor(basePost, post)); + } + + internal Color JudgeColor(PostClass basePost, PostClass targetPost) + { + Color cl; + if (targetPost.StatusId == basePost.InReplyToStatusId) + // @先 + cl = this.Theme.ColorAtTo; + else if (targetPost.IsMe) + // 自分=発言者 + cl = this.Theme.ColorSelf; + else if (targetPost.IsReply) + // 自分宛返信 + cl = this.Theme.ColorAtSelf; + else if (basePost.ReplyToList.Any(x => x.UserId == targetPost.UserId)) + // 返信先 + cl = this.Theme.ColorAtFromTarget; + else if (targetPost.ReplyToList.Any(x => x.UserId == basePost.UserId)) + // その人への返信 + cl = this.Theme.ColorAtTarget; + else if (targetPost.UserId == basePost.UserId) + // 発言者 + cl = this.Theme.ColorTarget; + else + // その他 + cl = this.Theme.ColorListBackcolor; + + return cl; + } + + private void ListView_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) + { + var listCache = this.listItemCache; + if (listCache != null && listCache.IsSupersetOf(e.StartIndex, e.EndIndex)) + { + // If the newly requested cache is a subset of the old cache, + // no need to rebuild everything, so do nothing. + return; + } + + // Now we need to rebuild the cache. + this.CreateCache(e.StartIndex, e.EndIndex); + } + + private void ListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) + { + var listCache = this.listItemCache; + if (listCache != null) + { + if (listCache.TryGetValue(e.ItemIndex, out var item, out _)) + { + e.Item = item; + return; + } + } + + // A cache miss, so create a new ListViewItem and pass it back. + try + { + e.Item = this.CreateItem(this.tab[e.ItemIndex]); + } + catch (Exception) + { + // 不正な要求に対する間に合わせの応答 + string[] sitem = { "", "", "", "", "", "", "", "" }; + e.Item = new ListViewItem(sitem); + } + } + + public void Dispose() + { + if (this.IsDisposed) + return; + + // RetrieveVirtualItem が呼ばれないようにするため 0 をセットする + this.listView.VirtualListSize = 0; + + this.UnregisterHandlers(); + this.PurgeCache(); + this.IsDisposed = true; + } + } + + public class ListViewItemCache + { + /// キャッシュする範囲の開始インデックス + public int StartIndex { get; } + + /// キャッシュする範囲の終了インデックス + public int EndIndex { get; } + + /// キャッシュされた範囲に対応する の組 + public (ListViewItem, PostClass)[] Cache { get; } + + /// キャッシュされたアイテムの件数 + public int Count + => this.EndIndex - this.StartIndex + 1; + + public ListViewItemCache(int startIndex, int endIndex, (ListViewItem, PostClass)[] cache) + { + if (!IsCacheSizeValid(startIndex, endIndex, cache)) + throw new ArgumentException("Cache size mismatch", nameof(cache)); + + this.StartIndex = startIndex; + this.EndIndex = endIndex; + this.Cache = cache; + } + + /// 指定されたインデックスがキャッシュの範囲内であるか判定します + /// がキャッシュの範囲内であれば true、それ以外は false + public bool Contains(int index) + => index >= this.StartIndex && index <= this.EndIndex; + + /// 指定されたインデックスの範囲が全てキャッシュの範囲内であるか判定します + /// から の範囲が全てキャッシュの範囲内であれば true、それ以外は false + public bool IsSupersetOf(int rangeStart, int rangeEnd) + => rangeStart >= this.StartIndex && rangeEnd <= this.EndIndex; + + /// 指定されたインデックスの をキャッシュから取得することを試みます + /// 取得に成功すれば true、それ以外は false + public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [NotNullWhen(true)] out PostClass? post) + { + if (this.Contains(index)) + { + (item, post) = this.Cache[index - this.StartIndex]; + return true; + } + else + { + item = null; + post = null; + return false; + } + } + + private static bool IsCacheSizeValid(int startIndex, int endIndex, T[] cache) + => cache.Length == (endIndex - startIndex + 1); + } +} diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 60b2d5cbb..359b5fc0a 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -180,61 +180,9 @@ public partial class TweenMain : OTBaseForm /// 発言保持クラス private readonly TabInformations statuses; + private TimelineListViewCache? listCache; private TimelineListViewDrawer? listDrawer; - /// - /// 現在表示している発言一覧の に対するキャッシュ - /// - /// - /// キャッシュクリアのために null が代入されることがあるため、 - /// 使用する場合には に対して直接メソッド等を呼び出さずに - /// 一旦ローカル変数に代入してから参照すること。 - /// - private ListViewItemCache? listItemCache = null; - - /// アイテムをキャッシュする対象の - /// キャッシュする範囲の開始インデックス - /// キャッシュする範囲の終了インデックス - /// ャッシュされた範囲に対応する の組 - internal record class ListViewItemCache( - ListView TargetList, - int StartIndex, - int EndIndex, - (ListViewItem, PostClass)[] Cache - ) - { - /// キャッシュされたアイテムの件数 - public int Count - => this.EndIndex - this.StartIndex + 1; - - /// 指定されたインデックスがキャッシュの範囲内であるか判定します - /// がキャッシュの範囲内であれば true、それ以外は false - public bool Contains(int index) - => index >= this.StartIndex && index <= this.EndIndex; - - /// 指定されたインデックスの範囲が全てキャッシュの範囲内であるか判定します - /// から の範囲が全てキャッシュの範囲内であれば true、それ以外は false - public bool IsSupersetOf(int rangeStart, int rangeEnd) - => rangeStart >= this.StartIndex && rangeEnd <= this.EndIndex; - - /// 指定されたインデックスの をキャッシュから取得することを試みます - /// 取得に成功すれば true、それ以外は false - public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [NotNullWhen(true)] out PostClass? post) - { - if (this.Contains(index)) - { - (item, post) = this.Cache[index - this.StartIndex]; - return true; - } - else - { - item = null; - post = null; - return false; - } - } - } - private bool isColumnChanged = false; private const int MaxWorderThreads = 20; @@ -954,23 +902,12 @@ private void RefreshTimeline() if (MyCommon.EndingFlag) return; // リストに反映&選択状態復元 - if (curListView.VirtualListSize != curTabModel.AllCount || isDelete) + if (this.listCache != null && (this.listCache.IsListSizeMismatched || isDelete)) { using (ControlTransaction.Update(curListView)) { - this.PurgeListViewItemCache(); - - try - { - // リスト件数更新 - curListView.VirtualListSize = curTabModel.AllCount; - } - catch (NullReferenceException ex) - { - // WinForms 内部で ListView.set_TopItem が発生させている例外 - // https://ja.osdn.net/ticket/browse.php?group_id=6526&tid=36588 - MyCommon.TraceOut(ex, $"TabType: {curTabModel.TabType}, Count: {curTabModel.AllCount}, ListSize: {curListView.VirtualListSize}"); - } + this.listCache.PurgeCache(); + this.listCache.UpdateListSize(); // 選択位置などを復元 this.RestoreListViewSelection(curListView, curTabModel, listSelections[curTabModel.TabName]); @@ -1417,144 +1354,12 @@ private async void MyList_SelectedIndexChanged(object sender, EventArgs e) this.statuses.SetReadAllTab(post.StatusId, read: true); // キャッシュの書き換え - this.ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色) + this.listCache?.ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色) - this.ColorizeList(); + this.listCache?.ColorizeList(); await this.selectionDebouncer.Call(); } - private void ChangeCacheStyleRead(bool read, int index) - { - var tabInfo = this.CurrentTab; - // Read:true=既読 false=未読 - // 未読管理していなかったら既読として扱う - if (!tabInfo.UnreadManage || - !this.settings.Common.UnreadManage) read = true; - - var listCache = this.listItemCache; - if (listCache == null) - return; - - // キャッシュに含まれていないアイテムは対象外 - if (!listCache.TryGetValue(index, out var itm, out var post)) - return; - - this.ChangeItemStyleRead(read, itm, post, (DetailsListView)listCache.TargetList); - } - - private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post, DetailsListView? dList) - { - Font fnt; - string star; - // フォント - if (read) - { - fnt = this.themeManager.FontReaded; - star = ""; - } - else - { - fnt = this.themeManager.FontUnread; - star = "★"; - } - if (item.SubItems[5].Text != star) - item.SubItems[5].Text = star; - - // 文字色 - Color cl; - if (post.IsFav) - cl = this.themeManager.ColorFav; - else if (post.RetweetedId != null) - cl = this.themeManager.ColorRetweet; - else if (post.IsOwl && (post.IsDm || this.settings.Common.OneWayLove)) - cl = this.themeManager.ColorOWL; - else if (read || !this.settings.Common.UseUnreadStyle) - cl = this.themeManager.ColorRead; - else - cl = this.themeManager.ColorUnread; - - if (dList == null || item.Index == -1) - { - item.ForeColor = cl; - if (this.settings.Common.UseUnreadStyle) - item.Font = fnt; - } - else - { - dList.Update(); - if (this.settings.Common.UseUnreadStyle) - dList.ChangeItemFontAndColor(item, cl, fnt); - else - dList.ChangeItemForeColor(item, cl); - } - } - - private void ColorizeList() - { - // Index:更新対象のListviewItem.Index。Colorを返す。 - // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - var post = this.CurrentTab.AnchorPost ?? this.CurrentPost; - if (post == null) - return; - - var listCache = this.listItemCache; - if (listCache == null) - return; - - var listView = (DetailsListView)listCache.TargetList; - - // ValidateRectが呼ばれる前に選択色などの描画を済ませておく - listView.Update(); - - foreach (var (listViewItem, cachedPost) in listCache.Cache) - { - var backColor = this.JudgeColor(post, cachedPost); - listView.ChangeItemBackColor(listViewItem, backColor); - } - } - - private void ColorizeList(ListViewItem item, PostClass post) - { - // Index:更新対象のListviewItem.Index。Colorを返す。 - // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - var basePost = this.CurrentTab.AnchorPost ?? this.CurrentPost; - if (basePost == null) - return; - - if (item.Index == -1) - item.BackColor = this.JudgeColor(basePost, post); - else - this.CurrentListView.ChangeItemBackColor(item, this.JudgeColor(basePost, post)); - } - - private Color JudgeColor(PostClass basePost, PostClass targetPost) - { - Color cl; - if (targetPost.StatusId == basePost.InReplyToStatusId) - // @先 - cl = this.themeManager.ColorAtTo; - else if (targetPost.IsMe) - // 自分=発言者 - cl = this.themeManager.ColorSelf; - else if (targetPost.IsReply) - // 自分宛返信 - cl = this.themeManager.ColorAtSelf; - else if (basePost.ReplyToList.Any(x => x.UserId == targetPost.UserId)) - // 返信先 - cl = this.themeManager.ColorAtFromTarget; - else if (targetPost.ReplyToList.Any(x => x.UserId == basePost.UserId)) - // その人への返信 - cl = this.themeManager.ColorAtTarget; - else if (targetPost.UserId == basePost.UserId) - // 発言者 - cl = this.themeManager.ColorTarget; - else - // その他 - cl = this.themeManager.ColorListBackcolor; - - return cl; - } - private void StatusTextHistoryBack() { if (!string.IsNullOrWhiteSpace(this.StatusText.Text)) @@ -1921,7 +1726,7 @@ await this.tw.Api.FavoritesCreate(post.RetweetedId ?? post.StatusId) { var idx = tab.IndexOf(statusId); if (idx != -1) - this.ChangeCacheStyleRead(post.IsRead, idx); + this.listCache?.ChangeCacheStyleRead(post.IsRead, idx); } var currentPost = this.CurrentPost; @@ -2034,7 +1839,7 @@ await this.tw.Api.FavoritesDestroy(post.RetweetedId ?? post.StatusId) continue; var post = tab.Posts[statusId]; - this.ChangeCacheStyleRead(post.IsRead, idx); + this.listCache?.ChangeCacheStyleRead(post.IsRead, idx); } } @@ -2287,7 +2092,7 @@ private async Task RefreshFollowerIdsAsync() this.StatusLabel.Text = Properties.Resources.UpdateFollowersMenuItem1_ClickText3; this.RefreshTimeline(); - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); this.CurrentListView.Refresh(); } catch (WebApiException ex) @@ -2361,7 +2166,7 @@ private async Task RefreshTwitterConfigurationAsync() } } - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); this.CurrentListView.Refresh(); } catch (WebApiException ex) @@ -2517,18 +2322,6 @@ private async Task FavoriteChange(bool favAdd, bool multiFavoriteChangeDialogEna } } - private PostClass GetCurTabPost(int index) - { - var listCache = this.listItemCache; - if (listCache != null) - { - if (listCache.TryGetValue(index, out _, out var post)) - return post; - } - - return this.CurrentTab[index]; - } - private async void AuthorOpenInBrowserMenuItem_Click(object sender, EventArgs e) { var post = this.CurrentPost; @@ -2645,7 +2438,7 @@ private void SetSortColumn(ComparerMode sortColumn) } } - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); var tab = this.CurrentTab; var post = this.CurrentPost; @@ -2849,14 +2642,14 @@ await this.tw.Api.StatusesDestroy(post.StatusId) else this.StatusLabel.Text = Properties.Resources.DeleteStripMenuItem_ClickText3; // 失敗 - this.PurgeListViewItemCache(); - using (ControlTransaction.Update(currentListView)) { - var currentTab = this.CurrentTab; - currentListView.VirtualListSize = currentTab.AllCount; + this.listCache?.PurgeCache(); + this.listCache?.UpdateListSize(); + currentListView.SelectedIndices.Clear(); + var currentTab = this.CurrentTab; if (currentTab.AllCount != 0) { int selectedIndex; @@ -2898,9 +2691,9 @@ private void ReadedStripMenuItem_Click(object sender, EventArgs e) { this.statuses.SetReadAllTab(statusId, read: true); var idx = tab.IndexOf(statusId); - this.ChangeCacheStyleRead(true, idx); + this.listCache?.ChangeCacheStyleRead(true, idx); } - this.ColorizeList(); + this.listCache?.ColorizeList(); } if (this.settings.Common.TabIconDisp) { @@ -2926,9 +2719,9 @@ private void UnreadStripMenuItem_Click(object sender, EventArgs e) { this.statuses.SetReadAllTab(statusId, read: false); var idx = tab.IndexOf(statusId); - this.ChangeCacheStyleRead(false, idx); + this.listCache?.ChangeCacheStyleRead(false, idx); } - this.ColorizeList(); + this.listCache?.ColorizeList(); } if (this.settings.Common.TabIconDisp) { @@ -3149,7 +2942,7 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) this.SetMainWindowTitle(); this.SetNotifyIconText(); - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); this.CurrentListView.Refresh(); this.ListTab.Refresh(); @@ -3220,7 +3013,7 @@ private void ApplyListViewIconSize(MyCommon.IconSizes iconSz) if (this.listDrawer != null) this.listDrawer.IconSize = iconSz; - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); } private void ResetColumns(DetailsListView list) @@ -3530,8 +3323,6 @@ public bool AddNewTab(TabModel tab, bool startup) listCustom.MouseClick += this.MyList_MouseClick; listCustom.ColumnReordered += this.MyList_ColumnReordered; listCustom.ColumnWidthChanged += this.MyList_ColumnWidthChanged; - listCustom.CacheVirtualItems += this.MyList_CacheVirtualItems; - listCustom.RetrieveVirtualItem += this.MyList_RetrieveVirtualItem; listCustom.HScrolled += this.MyList_HScrolled; } @@ -3626,8 +3417,6 @@ public bool RemoveSpecifiedTab(string tabName, bool confirm) listCustom.MouseClick -= this.MyList_MouseClick; listCustom.ColumnReordered -= this.MyList_ColumnReordered; listCustom.ColumnWidthChanged -= this.MyList_ColumnWidthChanged; - listCustom.CacheVirtualItems -= this.MyList_CacheVirtualItems; - listCustom.RetrieveVirtualItem -= this.MyList_RetrieveVirtualItem; listCustom.HScrolled -= this.MyList_HScrolled; var cols = listCustom.Columns.Cast().ToList(); @@ -3643,7 +3432,7 @@ public bool RemoveSpecifiedTab(string tabName, bool confirm) listCustom.ListViewItemSorter = null; // キャッシュのクリア - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); } tabPage.Dispose(); @@ -3655,7 +3444,7 @@ public bool RemoveSpecifiedTab(string tabName, bool confirm) private void ListTab_Deselected(object sender, TabControlEventArgs e) { - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); this.beforeSelectedTab = e.TabPage; } @@ -4089,141 +3878,6 @@ private int GetRestStatusCount(string statusText) private IMediaUploadService? GetSelectedImageService() => this.ImageSelector.Visible ? this.ImageSelector.SelectedService : null; - private void MyList_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) - { - if (sender != this.CurrentListView) - return; - - var listCache = this.listItemCache; - if (listCache?.TargetList == sender && listCache.IsSupersetOf(e.StartIndex, e.EndIndex)) - { - // If the newly requested cache is a subset of the old cache, - // no need to rebuild everything, so do nothing. - return; - } - - // Now we need to rebuild the cache. - this.CreateCache(e.StartIndex, e.EndIndex); - } - - private void MyList_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) - { - var listCache = this.listItemCache; - if (listCache?.TargetList == sender) - { - if (listCache.TryGetValue(e.ItemIndex, out var item, out _)) - { - e.Item = item; - return; - } - } - - // A cache miss, so create a new ListViewItem and pass it back. - var tabPage = (TabPage)((DetailsListView)sender).Parent; - var tab = this.statuses.Tabs[tabPage.Text]; - try - { - e.Item = this.CreateItem(tab, tab[e.ItemIndex]); - } - catch (Exception) - { - // 不正な要求に対する間に合わせの応答 - string[] sitem = { "", "", "", "", "", "", "", "" }; - e.Item = new ListViewItem(sitem); - } - } - - private void CreateCache(int startIndex, int endIndex) - { - var tabInfo = this.CurrentTab; - - if (tabInfo.AllCount == 0) - return; - - // インデックスを 0...(tabInfo.AllCount - 1) の範囲内にする - int FilterRange(int index) - => Math.Max(Math.Min(index, tabInfo.AllCount - 1), 0); - - // キャッシュ要求(要求範囲±30を作成) - startIndex = FilterRange(startIndex - 30); - endIndex = FilterRange(endIndex + 30); - - var cacheLength = endIndex - startIndex + 1; - - var tab = this.CurrentTab; - var posts = tabInfo[startIndex, endIndex]; // 配列で取得 - var listItems = Enumerable.Range(0, cacheLength) - .Select(x => this.CreateItem(tab, posts[x])) - .ToArray(); - - var listCache = new ListViewItemCache( - TargetList: this.CurrentListView, - StartIndex: startIndex, - EndIndex: endIndex, - Cache: Enumerable.Zip(listItems, posts, (x, y) => (x, y)).ToArray() - ); - - Interlocked.Exchange(ref this.listItemCache, listCache); - } - - /// - /// DetailsListView のための ListViewItem のキャッシュを消去する - /// - private void PurgeListViewItemCache() - => Interlocked.Exchange(ref this.listItemCache, null); - - private ListViewItem CreateItem(TabModel tab, PostClass post) - { - var mk = new StringBuilder(); - - if (post.FavoritedCount > 0) mk.Append("+" + post.FavoritedCount); - - ListViewItem itm; - if (post.RetweetedId == null) - { - string[] sitem = - { - "", - post.Nickname, - post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), - post.CreatedAt.ToLocalTimeString(this.settings.Common.DateTimeFormat), - post.ScreenName, - "", - mk.ToString(), - post.Source, - }; - itm = new ListViewItem(sitem); - } - else - { - string[] sitem = - { - "", - post.Nickname, - post.IsDeleted ? "(DELETED)" : post.AccessibleText.Replace('\n', ' '), - post.CreatedAt.ToLocalTimeString(this.settings.Common.DateTimeFormat), - post.ScreenName + Environment.NewLine + "(RT:" + post.RetweetedBy + ")", - "", - mk.ToString(), - post.Source, - }; - itm = new ListViewItem(sitem); - } - itm.Tag = post; - - var read = post.IsRead; - // 未読管理していなかったら既読として扱う - if (!tab.UnreadManage || !this.settings.Common.UnreadManage) - read = true; - - this.ChangeItemStyleRead(read, itm, post, null); - - if (tab.TabName == this.CurrentTabName) - this.ColorizeList(itm, post); - - return itm; - } - /// /// 全てのタブの振り分けルールを反映し直します /// @@ -4231,12 +3885,14 @@ private void ApplyPostFilters() { using (ControlTransaction.Cursor(this, Cursors.WaitCursor)) { - this.PurgeListViewItemCache(); this.statuses.FilterAll(); var listView = this.CurrentListView; using (ControlTransaction.Update(listView)) - listView.VirtualListSize = this.CurrentTab.AllCount; + { + this.listCache?.PurgeCache(); + this.listCache?.UpdateListSize(); + } foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) { @@ -5864,7 +5520,7 @@ private async Task GoInReplyToPostTree() currentPost.InReplyToStatusId = post.InReplyToStatusId; currentPost.InReplyToUser = post.InReplyToUser; currentPost.IsReply = post.IsReply; - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); var index = curTabClass.SelectedIndex; this.CurrentListView.RedrawItems(index, index, false); @@ -6878,7 +6534,7 @@ public void ChangeTabUnreadManage(string tabName, bool isManage) if (this.CurrentTabName == tabName) { - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); this.CurrentListView.Refresh(); } @@ -7445,8 +7101,8 @@ private void ClearTab(string tabName, bool showWarning) if (this.CurrentTabName == tabName) { this.CurrentTab.ClearAnchor(); - this.PurgeListViewItemCache(); - this.CurrentListView.VirtualListSize = 0; + this.listCache?.PurgeCache(); + this.listCache?.UpdateListSize(); } var tabIndex = this.statuses.Tabs.IndexOf(tabName); @@ -8425,10 +8081,7 @@ private void ListTabSelect(TabPage tabPage) { this.SetListProperty(); - if (!MyCommon.IsNullOrEmpty(this.statuses.SelectedTabName)) - this.CurrentListView.VirtualListSize = 0; - - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); this.statuses.SelectTab(tabPage.Text); @@ -8438,7 +8091,6 @@ private void ListTabSelect(TabPage tabPage) tab.ClearAnchor(); var listView = this.CurrentListView; - listView.VirtualListSize = tab.AllCount; listView.SelectItems(tab.SelectedIndices); if (this.Use2ColumnsMode) @@ -8459,6 +8111,10 @@ private void InitializeTimelineListView() var listView = this.CurrentListView; var tab = this.CurrentTab; + var newCache = new TimelineListViewCache(listView, tab, this.settings.Common, this.themeManager); + (this.listCache, var oldCache) = (newCache, this.listCache); + oldCache?.Dispose(); + var newDrawer = new TimelineListViewDrawer(listView, tab, this.iconCache, this.themeManager) { IconSize = this.settings.Common.IconSize, @@ -9211,9 +8867,9 @@ private async void SearchButton_Click(object sender, EventArgs e) cmb.Items.Insert(0, tb.SearchWords); cmb.Text = tb.SearchWords; cmb.SelectAll(); - this.PurgeListViewItemCache(); - listView.VirtualListSize = 0; this.statuses.ClearTabIds(tbName); + this.listCache?.PurgeCache(); + this.listCache?.UpdateListSize(); this.SaveConfigsTabs(); // 検索条件の保存 } @@ -10023,7 +9679,7 @@ private void SystemEvents_TimeChanged(object sender, EventArgs e) if (curTimeOffset != prevTimeOffset) { // タイムゾーンの変更を反映 - this.PurgeListViewItemCache(); + this.listCache?.PurgeCache(); this.CurrentListView.Refresh(); this.DispSelectedPost(forceupdate: true); From 6fafe43a81b1beeafa55b5e107c990bf3df0e444 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 25 Apr 2022 02:09:42 +0900 Subject: [PATCH 187/402] =?UTF-8?q?ListViewItemCache=E3=81=AE=E3=82=AD?= =?UTF-8?q?=E3=83=A3=E3=83=83=E3=82=B7=E3=83=A5=E3=81=8B=E3=82=89PostClass?= =?UTF-8?q?=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/ListViewItemCacheTest.cs | 38 +++++++++++++++--------- OpenTween/TimelineListViewCache.cs | 36 +++++++++++++--------- 2 files changed, 46 insertions(+), 28 deletions(-) diff --git a/OpenTween.Tests/ListViewItemCacheTest.cs b/OpenTween.Tests/ListViewItemCacheTest.cs index 4c7018060..e105beef6 100644 --- a/OpenTween.Tests/ListViewItemCacheTest.cs +++ b/OpenTween.Tests/ListViewItemCacheTest.cs @@ -20,8 +20,8 @@ // Boston, MA 02110-1301, USA. using System; +using System.Linq; using System.Windows.Forms; -using OpenTween.Models; using Xunit; namespace OpenTween @@ -34,17 +34,17 @@ public void Cache_InvalidSizeTest() var startIndex = 10; var endIndex = 19; Assert.Throws( - () => new ListViewItemCache(startIndex, endIndex, new (ListViewItem, PostClass)[9]) + () => new ListViewItemCache(startIndex, endIndex, new ListViewItem[9]) ); Assert.Throws( - () => new ListViewItemCache(startIndex, endIndex, new (ListViewItem, PostClass)[11]) + () => new ListViewItemCache(startIndex, endIndex, new ListViewItem[11]) ); } [Fact] public void Count_Test() { - var cache = new ListViewItemCache(10, 19, new (ListViewItem, PostClass)[10]); + var cache = new ListViewItemCache(10, 19, new ListViewItem[10]); Assert.Equal(10, cache.Count); } @@ -55,7 +55,7 @@ public void Count_Test() [InlineData(20, false)] public void Contains_Test(int index, bool expected) { - var cache = new ListViewItemCache(10, 19, new (ListViewItem, PostClass)[10]); + var cache = new ListViewItemCache(10, 19, new ListViewItem[10]); Assert.Equal(expected, cache.Contains(index)); } @@ -66,7 +66,7 @@ public void Contains_Test(int index, bool expected) [InlineData(10, 20, false)] public void IsSupersetOf_Test(int start, int end, bool expected) { - var cache = new ListViewItemCache(10, 19, new (ListViewItem, PostClass)[10]); + var cache = new ListViewItemCache(10, 19, new ListViewItem[10]); Assert.Equal(expected, cache.IsSupersetOf(start, end)); } @@ -74,23 +74,33 @@ public void IsSupersetOf_Test(int start, int end, bool expected) public void TryGetValue_FoundTest() { var item = new ListViewItem(); - var post = new PostClass(); - var cache = new ListViewItemCache(10, 10, new[] { (item, post) }); + var cache = new ListViewItemCache(10, 10, new[] { item }); - Assert.True(cache.TryGetValue(10, out var actualItem, out var actualPost)); + Assert.True(cache.TryGetValue(10, out var actualItem)); Assert.Equal(item, actualItem); - Assert.Equal(post, actualPost); } [Fact] public void TryGetValue_NotFoundTest() { var item = new ListViewItem(); - var post = new PostClass(); - var cache = new ListViewItemCache(10, 10, new[] { (item, post) }); + var cache = new ListViewItemCache(10, 10, new[] { item }); - Assert.False(cache.TryGetValue(9, out _, out _)); - Assert.False(cache.TryGetValue(11, out _, out _)); + Assert.False(cache.TryGetValue(9, out _)); + Assert.False(cache.TryGetValue(11, out _)); + } + + [Fact] + public void WithIndex_Test() + { + var item1 = new ListViewItem(); + var item2 = new ListViewItem(); + var cache = new ListViewItemCache(10, 11, new[] { item1, item2 }); + + var actualArray = cache.WithIndex().ToArray(); + Assert.Equal(2, actualArray.Length); + Assert.Equal((item1, 10), actualArray[0]); + Assert.Equal((item2, 11), actualArray[1]); } } } diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index ae1be743a..5e79ef589 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -27,6 +27,7 @@ #nullable enable using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Drawing; using System.Linq; @@ -128,7 +129,7 @@ int FilterRange(int index) var listCache = new ListViewItemCache( startIndex, endIndex, - Enumerable.Zip(listItems, posts, (x, y) => (x, y)).ToArray() + listItems ); Interlocked.Exchange(ref this.listItemCache, listCache); @@ -202,9 +203,10 @@ public void ChangeCacheStyleRead(bool read, int index) return; // キャッシュに含まれていないアイテムは対象外 - if (!listCache.TryGetValue(index, out var itm, out var post)) + if (!listCache.TryGetValue(index, out var itm)) return; + var post = this.tab[index]; this.ChangeItemStyleRead(read, itm, post); } @@ -259,8 +261,8 @@ public void ColorizeList() { // Index:更新対象のListviewItem.Index。Colorを返す。 // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - var post = this.tab.AnchorPost ?? this.tab.SelectedPost; - if (post == null) + var basePost = this.tab.AnchorPost ?? this.tab.SelectedPost; + if (basePost == null) return; var listCache = this.listItemCache; @@ -270,9 +272,10 @@ public void ColorizeList() // ValidateRectが呼ばれる前に選択色などの描画を済ませておく this.listView.Update(); - foreach (var (listViewItem, cachedPost) in listCache.Cache) + foreach (var (listViewItem, index) in listCache.WithIndex()) { - var backColor = this.JudgeColor(post, cachedPost); + var post = this.tab[index]; + var backColor = this.JudgeColor(basePost, post); this.listView.ChangeItemBackColor(listViewItem, backColor); } } @@ -338,7 +341,7 @@ private void ListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEven var listCache = this.listItemCache; if (listCache != null) { - if (listCache.TryGetValue(e.ItemIndex, out var item, out _)) + if (listCache.TryGetValue(e.ItemIndex, out var item)) { e.Item = item; return; @@ -380,14 +383,14 @@ public class ListViewItemCache /// キャッシュする範囲の終了インデックス public int EndIndex { get; } - /// キャッシュされた範囲に対応する の組 - public (ListViewItem, PostClass)[] Cache { get; } + /// キャッシュされた範囲に対応する の配列 + public ListViewItem[] Cache { get; } /// キャッシュされたアイテムの件数 public int Count => this.EndIndex - this.StartIndex + 1; - public ListViewItemCache(int startIndex, int endIndex, (ListViewItem, PostClass)[] cache) + public ListViewItemCache(int startIndex, int endIndex, ListViewItem[] cache) { if (!IsCacheSizeValid(startIndex, endIndex, cache)) throw new ArgumentException("Cache size mismatch", nameof(cache)); @@ -407,23 +410,28 @@ public bool Contains(int index) public bool IsSupersetOf(int rangeStart, int rangeEnd) => rangeStart >= this.StartIndex && rangeEnd <= this.EndIndex; - /// 指定されたインデックスの をキャッシュから取得することを試みます + /// 指定されたインデックスの をキャッシュから取得することを試みます /// 取得に成功すれば true、それ以外は false - public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, [NotNullWhen(true)] out PostClass? post) + public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item) { if (this.Contains(index)) { - (item, post) = this.Cache[index - this.StartIndex]; + item = this.Cache[index - this.StartIndex]; return true; } else { item = null; - post = null; return false; } } + public IEnumerable<(ListViewItem Item, int Index)> WithIndex() + { + foreach (var (item, index) in this.Cache.WithIndex()) + yield return (item, index + this.StartIndex); + } + private static bool IsCacheSizeValid(int startIndex, int endIndex, T[] cache) => cache.Length == (endIndex - startIndex + 1); } From 09bdd089a14e30ac0e3f6ad1bab7f21571a520fe Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 25 Apr 2022 03:42:35 +0900 Subject: [PATCH 188/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E8=83=8C=E6=99=AF=E8=89=B2=E3=83=BB=E5=89=8D=E6=99=AF?= =?UTF-8?q?=E8=89=B2=E3=83=BB=E3=83=95=E3=82=A9=E3=83=B3=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=A1=A8=E3=81=99=E5=88=97=E6=8C=99=E4=BD=93=E3=82=92=E5=AE=9A?= =?UTF-8?q?=E7=BE=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TimelineListViewCacheTest.cs | 36 ++++ OpenTween/TimelineListViewCache.cs | 215 +++++++++++++------ OpenTween/Tween.cs | 15 +- 3 files changed, 188 insertions(+), 78 deletions(-) diff --git a/OpenTween.Tests/TimelineListViewCacheTest.cs b/OpenTween.Tests/TimelineListViewCacheTest.cs index a63bee002..bb6bc201a 100644 --- a/OpenTween.Tests/TimelineListViewCacheTest.cs +++ b/OpenTween.Tests/TimelineListViewCacheTest.cs @@ -104,6 +104,24 @@ public void CreateItem_UnreadTest() Assert.Equal("★", item.SubItems[5].Text); } + [Fact] + public void CreateItem_UnreadManageDisabledTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, new(), theme); + + var post = this.CreatePost(); + post.IsRead = false; + + // 未読管理が無効な場合は未読状態に関わらず未読マークを表示しない + tab.UnreadManage = false; + + var item = cache.CreateItem(post); + Assert.Equal("", item.SubItems[5].Text); + } + [Fact] public void CreateItem_FavoritesTest() { @@ -198,6 +216,24 @@ public void CreateItem_Font_UnreadStyleDisabledTest() Assert.Equal(theme.FontReaded, item.Font); } + [Fact] + public void CreateItem_Font_UnreadManageDisabledTest() + { + var tab = new PublicSearchTabModel("tab"); + var settingCommon = new SettingCommon(); + using var listView = new DetailsListView(); + using var theme = new ThemeManager(new()); + using var cache = new TimelineListViewCache(listView, tab, settingCommon, theme); + + var post = this.CreatePost(); + post.IsRead = false; + + tab.UnreadManage = false; + + var item = cache.CreateItem(post); + Assert.Equal(theme.FontReaded, item.Font); + } + [Fact] public void CreateItem_ForeColor_Test() { diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index 5e79ef589..c82fed775 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -180,24 +180,14 @@ internal ListViewItem CreateItem(PostClass post) } itm.Tag = post; - var read = post.IsRead; - // 未読管理していなかったら既読として扱う - if (!this.tab.UnreadManage || !this.settings.UnreadManage) - read = true; - - this.ChangeItemStyleRead(read, itm, post); + this.ChangeItemStyleRead(itm, post); this.ColorizeList(itm, post); return itm; } - public void ChangeCacheStyleRead(bool read, int index) + public void ChangeCacheStyleRead(int index) { - // Read:true=既読 false=未読 - // 未読管理していなかったら既読として扱う - if (!this.tab.UnreadManage || - !this.settings.UnreadManage) read = true; - var listCache = this.listItemCache; if (listCache == null) return; @@ -207,53 +197,27 @@ public void ChangeCacheStyleRead(bool read, int index) return; var post = this.tab[index]; - this.ChangeItemStyleRead(read, itm, post); + this.ChangeItemStyleRead(itm, post); } - private void ChangeItemStyleRead(bool read, ListViewItem item, PostClass post) + private void ChangeItemStyleRead(ListViewItem item, PostClass post) { - Font fnt; - string star; - // フォント - if (read) - { - fnt = this.Theme.FontReaded; - star = ""; - } - else - { - fnt = this.Theme.FontUnread; - star = "★"; - } + var star = this.GetUnreadMark(this.DetermineUnreadMark(post)); + var fnt = this.GetFont(this.DetermineFont(post)); + var cl = this.GetForeColor(this.DetermineForeColor(post)); + if (item.SubItems[5].Text != star) item.SubItems[5].Text = star; - // 文字色 - Color cl; - if (post.IsFav) - cl = this.Theme.ColorFav; - else if (post.RetweetedId != null) - cl = this.Theme.ColorRetweet; - else if (post.IsOwl && (post.IsDm || this.settings.OneWayLove)) - cl = this.Theme.ColorOWL; - else if (read || !this.settings.UseUnreadStyle) - cl = this.Theme.ColorRead; - else - cl = this.Theme.ColorUnread; - if (item.Index == -1) { item.ForeColor = cl; - if (this.settings.UseUnreadStyle) - item.Font = fnt; + item.Font = fnt; } else { this.listView.Update(); - if (this.settings.UseUnreadStyle) - this.listView.ChangeItemFontAndColor(item, cl, fnt); - else - this.listView.ChangeItemForeColor(item, cl); + this.listView.ChangeItemFontAndColor(item, cl, fnt); } } @@ -295,31 +259,118 @@ private void ColorizeList(ListViewItem item, PostClass post) } internal Color JudgeColor(PostClass basePost, PostClass targetPost) + => this.GetBackColor(this.DetermineBackColor(basePost, targetPost)); + + private string GetUnreadMark(bool unreadMark) + => unreadMark ? "★" : ""; + + private Color GetBackColor(ListItemBackColor backColor) { - Color cl; - if (targetPost.StatusId == basePost.InReplyToStatusId) - // @先 - cl = this.Theme.ColorAtTo; - else if (targetPost.IsMe) - // 自分=発言者 - cl = this.Theme.ColorSelf; - else if (targetPost.IsReply) - // 自分宛返信 - cl = this.Theme.ColorAtSelf; - else if (basePost.ReplyToList.Any(x => x.UserId == targetPost.UserId)) - // 返信先 - cl = this.Theme.ColorAtFromTarget; - else if (targetPost.ReplyToList.Any(x => x.UserId == basePost.UserId)) - // その人への返信 - cl = this.Theme.ColorAtTarget; - else if (targetPost.UserId == basePost.UserId) - // 発言者 - cl = this.Theme.ColorTarget; - else - // その他 - cl = this.Theme.ColorListBackcolor; + return backColor switch + { + ListItemBackColor.Self => this.Theme.ColorSelf, + ListItemBackColor.AtSelf => this.Theme.ColorAtSelf, + ListItemBackColor.Target => this.Theme.ColorTarget, + ListItemBackColor.AtTarget => this.Theme.ColorAtTarget, + ListItemBackColor.AtFromTarget => this.Theme.ColorAtFromTarget, + ListItemBackColor.AtTo => this.Theme.ColorAtTo, + _ => this.Theme.ColorListBackcolor, + }; + } + + private Color GetForeColor(ListItemForeColor foreColor) + { + return foreColor switch + { + ListItemForeColor.Fav => this.Theme.ColorFav, + ListItemForeColor.Retweet => this.Theme.ColorRetweet, + ListItemForeColor.OWL => this.Theme.ColorOWL, + ListItemForeColor.Unread => this.Theme.ColorUnread, + _ => this.Theme.ColorRead, + }; + } + + private Font GetFont(ListItemFont font) + { + return font switch + { + ListItemFont.Unread => this.Theme.FontUnread, + _ => this.Theme.FontReaded, + }; + } + + private bool DetermineUnreadMark(PostClass post) + { + // 未読管理していなかったら既読として扱う + var unreadManageEnabled = this.tab.UnreadManage && this.settings.UnreadManage; + if (!unreadManageEnabled) + return false; + + return !post.IsRead; + } - return cl; + private ListItemBackColor DetermineBackColor(PostClass? basePost, PostClass post) + { + if (basePost == null) + return ListItemBackColor.None; + + // @先 + if (post.StatusId == basePost.InReplyToStatusId) + return ListItemBackColor.AtTo; + + // 自分=発言者 + if (post.IsMe) + return ListItemBackColor.Self; + + // 自分宛返信 + if (post.IsReply) + return ListItemBackColor.AtSelf; + + // 返信先 + if (basePost.ReplyToList.Any(x => x.UserId == post.UserId)) + return ListItemBackColor.AtFromTarget; + + // その人への返信 + if (post.ReplyToList.Any(x => x.UserId == basePost.UserId)) + return ListItemBackColor.AtTarget; + + // 発言者 + if (post.UserId == basePost.UserId) + return ListItemBackColor.Target; + + // その他 + return ListItemBackColor.None; + } + + private ListItemForeColor DetermineForeColor(PostClass post) + { + if (post.IsFav) + return ListItemForeColor.Fav; + + if (post.RetweetedId != null) + return ListItemForeColor.Retweet; + + if (post.IsOwl && (post.IsDm || this.settings.OneWayLove)) + return ListItemForeColor.OWL; + + var unreadManageEnabled = this.tab.UnreadManage && this.settings.UnreadManage; + var useUnreadStyle = unreadManageEnabled && this.settings.UseUnreadStyle; + + if (useUnreadStyle && !post.IsRead) + return ListItemForeColor.Unread; + + return ListItemForeColor.None; + } + + private ListItemFont DetermineFont(PostClass post) + { + var unreadManageEnabled = this.tab.UnreadManage && this.settings.UnreadManage; + var useUnreadStyle = unreadManageEnabled && this.settings.UseUnreadStyle; + + if (useUnreadStyle && !post.IsRead) + return ListItemFont.Unread; + + return ListItemFont.Readed; } private void ListView_CacheVirtualItems(object sender, CacheVirtualItemsEventArgs e) @@ -375,6 +426,32 @@ public void Dispose() } } + public enum ListItemBackColor + { + None, + Self, + AtSelf, + Target, + AtTarget, + AtFromTarget, + AtTo, + } + + public enum ListItemForeColor + { + None, + Fav, + Retweet, + OWL, + Unread, + } + + public enum ListItemFont + { + Readed, + Unread, + } + public class ListViewItemCache { /// キャッシュする範囲の開始インデックス diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 359b5fc0a..58cd25bc4 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1354,7 +1354,7 @@ private async void MyList_SelectedIndexChanged(object sender, EventArgs e) this.statuses.SetReadAllTab(post.StatusId, read: true); // キャッシュの書き換え - this.listCache?.ChangeCacheStyleRead(true, index); // 既読へ(フォント、文字色) + this.listCache?.ChangeCacheStyleRead(index); // 既読へ(フォント、文字色) this.listCache?.ColorizeList(); await this.selectionDebouncer.Call(); @@ -1726,7 +1726,7 @@ await this.tw.Api.FavoritesCreate(post.RetweetedId ?? post.StatusId) { var idx = tab.IndexOf(statusId); if (idx != -1) - this.listCache?.ChangeCacheStyleRead(post.IsRead, idx); + this.listCache?.ChangeCacheStyleRead(idx); } var currentPost = this.CurrentPost; @@ -1835,11 +1835,8 @@ await this.tw.Api.FavoritesDestroy(post.RetweetedId ?? post.StatusId) foreach (var statusId in successIds) { var idx = tab.IndexOf(statusId); - if (idx == -1) - continue; - - var post = tab.Posts[statusId]; - this.listCache?.ChangeCacheStyleRead(post.IsRead, idx); + if (idx != -1) + this.listCache?.ChangeCacheStyleRead(idx); } } @@ -2691,7 +2688,7 @@ private void ReadedStripMenuItem_Click(object sender, EventArgs e) { this.statuses.SetReadAllTab(statusId, read: true); var idx = tab.IndexOf(statusId); - this.listCache?.ChangeCacheStyleRead(true, idx); + this.listCache?.ChangeCacheStyleRead(idx); } this.listCache?.ColorizeList(); } @@ -2719,7 +2716,7 @@ private void UnreadStripMenuItem_Click(object sender, EventArgs e) { this.statuses.SetReadAllTab(statusId, read: false); var idx = tab.IndexOf(statusId); - this.listCache?.ChangeCacheStyleRead(false, idx); + this.listCache?.ChangeCacheStyleRead(idx); } this.listCache?.ColorizeList(); } From 6cba2a0b55f2f07093b199399da12162ad52490f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Mon, 25 Apr 2022 23:36:17 +0900 Subject: [PATCH 189/402] =?UTF-8?q?DetailsListView=E3=81=A7=E5=86=8D?= =?UTF-8?q?=E6=8F=8F=E7=94=BB=E3=81=99=E3=82=8B=E8=A1=8C=E3=81=AE=E7=AF=84?= =?UTF-8?q?=E5=9B=B2=E3=82=92=E9=99=90=E5=AE=9A=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/MyCommonTest.cs | 23 ++++++++++++ OpenTween/DetailsListView.cs | 62 +++++++++++++++++++-------------- OpenTween/MyCommon.cs | 31 +++++++++++++++++ 3 files changed, 90 insertions(+), 26 deletions(-) diff --git a/OpenTween.Tests/MyCommonTest.cs b/OpenTween.Tests/MyCommonTest.cs index 0efa75fc2..dff7e0a92 100644 --- a/OpenTween.Tests/MyCommonTest.cs +++ b/OpenTween.Tests/MyCommonTest.cs @@ -354,5 +354,28 @@ public void CreateBrowserProcessStartInfo_QuotedBrowserPathWithArgsTest() Assert.Equal("/hoge \"https://example.com/\"", startInfo.Arguments); Assert.False(startInfo.UseShellExecute); } + + public static readonly TheoryData ToRangeChunkTestCase = new() + { + { + new[] { 1 }, + new[] { (1, 1) } + }, + { + new[] { 1, 2 }, + new[] { (1, 2) } + }, + { + new[] { 1, 3 }, + new[] { (1, 1), (3, 3) } + }, + }; + + [Theory] + [MemberData(nameof(ToRangeChunkTestCase))] + public void ToRangeChunk_Test(int[] values, (int Start, int End)[] expected) + { + Assert.Equal(expected, MyCommon.ToRangeChunk(values)); + } } } diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index 2f020d1cb..ae45be8af 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -40,7 +40,7 @@ namespace OpenTween.OpenTweenCustomControl { public sealed class DetailsListView : ListView { - private Rectangle changeBounds; + private (int Start, int End)? redrawRange = null; [DefaultValue(null)] public ContextMenuStrip? ColumnHeaderContextMenuStrip { get; set; } @@ -122,7 +122,10 @@ public void ChangeItemBackColor(ListViewItem item, Color backColor) return; item.BackColor = backColor; - this.RefreshItemBounds(item); + + var index = item.Index; + if (index != -1) + this.RefreshItemsRange(index, index); } public void ChangeItemForeColor(ListViewItem item, Color foreColor) @@ -131,7 +134,10 @@ public void ChangeItemForeColor(ListViewItem item, Color foreColor) return; item.ForeColor = foreColor; - this.RefreshItemBounds(item); + + var index = item.Index; + if (index != -1) + this.RefreshItemsRange(index, index); } public void ChangeItemFontAndColor(ListViewItem item, Color foreColor, Font fnt) @@ -141,27 +147,40 @@ public void ChangeItemFontAndColor(ListViewItem item, Color foreColor, Font fnt) item.ForeColor = foreColor; item.Font = fnt; - this.RefreshItemBounds(item); + + var index = item.Index; + if (index != -1) + this.RefreshItemsRange(index, index); } - private void RefreshItemBounds(ListViewItem item) + private void RefreshItemsRange(int start, int end) { try { - var itemBounds = item.Bounds; - var drawBounds = Rectangle.Intersect(this.ClientRectangle, itemBounds); - if (drawBounds == Rectangle.Empty) - return; - - this.changeBounds = drawBounds; - this.Update(); - this.changeBounds = Rectangle.Empty; + this.redrawRange = (start, end); + this.ValidateAll(); + this.RedrawItems(start, end, invalidateOnly: false); + } + finally + { + this.redrawRange = null; } - catch (ArgumentException) + } + + /// 領域を全て有効化する(再描画が必要な領域から除外する) + private void ValidateAll() + => NativeMethods.ValidateRect(this.Handle, IntPtr.Zero); + + protected override void OnDrawItem(DrawListViewItemEventArgs e) + { + if (this.redrawRange is (int start, int end)) { - // タイミングによりBoundsプロパティが取れない? - this.changeBounds = Rectangle.Empty; + var index = e.ItemIndex; + if (index < start || index > end) + return; } + + base.OnDrawItem(e); } [StructLayout(LayoutKind.Sequential)] @@ -176,7 +195,6 @@ private struct NMHDR protected override void WndProc(ref Message m) { const int WM_ERASEBKGND = 0x14; - const int WM_PAINT = 0xF; const int WM_MOUSEWHEEL = 0x20A; const int WM_MOUSEHWHEEL = 0x20E; const int WM_HSCROLL = 0x114; @@ -197,17 +215,9 @@ protected override void WndProc(ref Message m) switch (m.Msg) { case WM_ERASEBKGND: - if (this.changeBounds != Rectangle.Empty) + if (this.redrawRange != null) m.Msg = 0; break; - case WM_PAINT: - if (this.changeBounds != Rectangle.Empty) - { - NativeMethods.ValidateRect(this.Handle, IntPtr.Zero); - this.Invalidate(this.changeBounds); - this.changeBounds = Rectangle.Empty; - } - break; case WM_HSCROLL: this.HScrolled?.Invoke(this, EventArgs.Empty); break; diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index c60c0ef05..d26e6a3f8 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -1042,5 +1042,36 @@ public static ProcessStartInfo CreateBrowserProcessStartInfo(string? browserPath UseShellExecute = false, }; } + + public static IEnumerable<(int Start, int End)> ToRangeChunk(IEnumerable values) + { + var start = -1; + var end = -1; + + foreach (var value in values.OrderBy(x => x)) + { + if (start == -1) + { + start = value; + end = value; + } + else + { + if (value == end + 1) + { + end = value; + } + else + { + yield return (start, end); + start = value; + end = value; + } + } + } + + if (start != -1) + yield return (start, end); + } } } From 48485de32718f05aa8f6f5a47561061f9b072375 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 26 Apr 2022 00:00:57 +0900 Subject: [PATCH 190/402] =?UTF-8?q?DetailsListView.RefreshItems=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/DetailsListView.cs | 39 ++++++------------------------ OpenTween/TimelineListViewCache.cs | 34 ++++++++++++++------------ 2 files changed, 27 insertions(+), 46 deletions(-) diff --git a/OpenTween/DetailsListView.cs b/OpenTween/DetailsListView.cs index ae45be8af..a1df119ea 100644 --- a/OpenTween/DetailsListView.cs +++ b/OpenTween/DetailsListView.cs @@ -116,41 +116,19 @@ public void SelectAllItems() this.OnSelectedIndexChanged(EventArgs.Empty); } - public void ChangeItemBackColor(ListViewItem item, Color backColor) + public void RefreshItem(int index) { - if (item.BackColor == backColor) - return; - - item.BackColor = backColor; - - var index = item.Index; - if (index != -1) - this.RefreshItemsRange(index, index); - } - - public void ChangeItemForeColor(ListViewItem item, Color foreColor) - { - if (item.ForeColor == foreColor) - return; - - item.ForeColor = foreColor; - - var index = item.Index; - if (index != -1) - this.RefreshItemsRange(index, index); + this.ValidateAll(); + this.RefreshItemsRange(index, index); } - public void ChangeItemFontAndColor(ListViewItem item, Color foreColor, Font fnt) + public void RefreshItems(IEnumerable indices) { - if (item.ForeColor == foreColor && item.Font.Equals(fnt)) - return; - - item.ForeColor = foreColor; - item.Font = fnt; + var chunks = MyCommon.ToRangeChunk(indices); + this.ValidateAll(); - var index = item.Index; - if (index != -1) - this.RefreshItemsRange(index, index); + foreach (var (start, end) in chunks) + this.RefreshItemsRange(start, end); } private void RefreshItemsRange(int start, int end) @@ -158,7 +136,6 @@ private void RefreshItemsRange(int start, int end) try { this.redrawRange = (start, end); - this.ValidateAll(); this.RedrawItems(start, end, invalidateOnly: false); } finally diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index c82fed775..168f84402 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -206,19 +206,18 @@ private void ChangeItemStyleRead(ListViewItem item, PostClass post) var fnt = this.GetFont(this.DetermineFont(post)); var cl = this.GetForeColor(this.DetermineForeColor(post)); + var index = item.Index; + if (index != -1) + this.listView.Update(); + if (item.SubItems[5].Text != star) item.SubItems[5].Text = star; - if (item.Index == -1) - { - item.ForeColor = cl; - item.Font = fnt; - } - else - { - this.listView.Update(); - this.listView.ChangeItemFontAndColor(item, cl, fnt); - } + item.ForeColor = cl; + item.Font = fnt; + + if (index != -1) + this.listView.RefreshItem(index); } public void ColorizeList() @@ -240,7 +239,8 @@ public void ColorizeList() { var post = this.tab[index]; var backColor = this.JudgeColor(basePost, post); - this.listView.ChangeItemBackColor(listViewItem, backColor); + listViewItem.BackColor = backColor; + this.listView.RefreshItem(index); } } @@ -252,10 +252,14 @@ private void ColorizeList(ListViewItem item, PostClass post) if (basePost == null) return; - if (item.Index == -1) - item.BackColor = this.JudgeColor(basePost, post); - else - this.listView.ChangeItemBackColor(item, this.JudgeColor(basePost, post)); + var index = item.Index; + if (index != -1) + this.listView.Update(); + + item.BackColor = this.JudgeColor(basePost, post); + + if (index != -1) + this.listView.RefreshItem(index); } internal Color JudgeColor(PostClass basePost, PostClass targetPost) From 543c9606d72536a0ab514c3ed90868f94bb1ab5b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 26 Apr 2022 01:42:22 +0900 Subject: [PATCH 191/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E3=82=B9=E3=82=BF=E3=82=A4=E3=83=AB=E6=83=85=E5=A0=B1?= =?UTF-8?q?=E3=82=82=E3=82=AD=E3=83=A3=E3=83=83=E3=82=B7=E3=83=A5=E5=AF=BE?= =?UTF-8?q?=E8=B1=A1=E3=81=A8=E3=81=97=E3=80=81=E3=82=B9=E3=82=BF=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E3=81=AB=E5=A4=89=E5=8C=96=E3=81=8C=E7=94=9F=E3=81=98?= =?UTF-8?q?=E3=81=9F=E8=A1=8C=E3=81=AE=E3=81=BF=E5=86=8D=E6=8F=8F=E7=94=BB?= =?UTF-8?q?=E3=82=92=E8=A1=8C=E3=81=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/ListViewItemCacheTest.cs | 56 ++++-- OpenTween.Tests/TimelineListViewCacheTest.cs | 103 +++++++---- OpenTween/TimelineListViewCache.cs | 170 ++++++++++--------- OpenTween/Tween.cs | 15 +- 4 files changed, 212 insertions(+), 132 deletions(-) diff --git a/OpenTween.Tests/ListViewItemCacheTest.cs b/OpenTween.Tests/ListViewItemCacheTest.cs index e105beef6..005f37fab 100644 --- a/OpenTween.Tests/ListViewItemCacheTest.cs +++ b/OpenTween.Tests/ListViewItemCacheTest.cs @@ -34,17 +34,17 @@ public void Cache_InvalidSizeTest() var startIndex = 10; var endIndex = 19; Assert.Throws( - () => new ListViewItemCache(startIndex, endIndex, new ListViewItem[9]) + () => new ListViewItemCache(startIndex, endIndex, new (ListViewItem, ListItemStyle)[9]) ); Assert.Throws( - () => new ListViewItemCache(startIndex, endIndex, new ListViewItem[11]) + () => new ListViewItemCache(startIndex, endIndex, new (ListViewItem, ListItemStyle)[11]) ); } [Fact] public void Count_Test() { - var cache = new ListViewItemCache(10, 19, new ListViewItem[10]); + var cache = new ListViewItemCache(10, 19, new (ListViewItem, ListItemStyle)[10]); Assert.Equal(10, cache.Count); } @@ -55,7 +55,7 @@ public void Count_Test() [InlineData(20, false)] public void Contains_Test(int index, bool expected) { - var cache = new ListViewItemCache(10, 19, new ListViewItem[10]); + var cache = new ListViewItemCache(10, 19, new (ListViewItem, ListItemStyle)[10]); Assert.Equal(expected, cache.Contains(index)); } @@ -66,7 +66,7 @@ public void Contains_Test(int index, bool expected) [InlineData(10, 20, false)] public void IsSupersetOf_Test(int start, int end, bool expected) { - var cache = new ListViewItemCache(10, 19, new ListViewItem[10]); + var cache = new ListViewItemCache(10, 19, new (ListViewItem, ListItemStyle)[10]); Assert.Equal(expected, cache.IsSupersetOf(start, end)); } @@ -74,33 +74,63 @@ public void IsSupersetOf_Test(int start, int end, bool expected) public void TryGetValue_FoundTest() { var item = new ListViewItem(); - var cache = new ListViewItemCache(10, 10, new[] { item }); + var style = new ListItemStyle(); + var cache = new ListViewItemCache(10, 10, new[] { (item, style) }); - Assert.True(cache.TryGetValue(10, out var actualItem)); + Assert.True(cache.TryGetValue(10, out var actualItem, out var actualStyle)); Assert.Equal(item, actualItem); + Assert.Equal(style, actualStyle); } [Fact] public void TryGetValue_NotFoundTest() { var item = new ListViewItem(); - var cache = new ListViewItemCache(10, 10, new[] { item }); + var style = new ListItemStyle(); + var cache = new ListViewItemCache(10, 10, new[] { (item, style) }); - Assert.False(cache.TryGetValue(9, out _)); - Assert.False(cache.TryGetValue(11, out _)); + Assert.False(cache.TryGetValue(9, out _, out _)); + Assert.False(cache.TryGetValue(11, out _, out _)); } [Fact] public void WithIndex_Test() { var item1 = new ListViewItem(); + var style1 = new ListItemStyle(); var item2 = new ListViewItem(); - var cache = new ListViewItemCache(10, 11, new[] { item1, item2 }); + var style2 = new ListItemStyle(); + var cache = new ListViewItemCache(10, 11, new[] { (item1, style1), (item2, style2) }); var actualArray = cache.WithIndex().ToArray(); Assert.Equal(2, actualArray.Length); - Assert.Equal((item1, 10), actualArray[0]); - Assert.Equal((item2, 11), actualArray[1]); + Assert.Equal((item1, style1, 10), actualArray[0]); + Assert.Equal((item2, style2, 11), actualArray[1]); + } + + [Fact] + public void UpdateStyle_Test() + { + var item = new ListViewItem(); + var style = new ListItemStyle { UnreadMark = false }; + var cache = new ListViewItemCache(10, 10, new[] { (item, style) }); + + var newStyle = style with { UnreadMark = true }; + cache.UpdateStyle(10, newStyle); + + Assert.True(cache.TryGetValue(10, out _, out var actualStyle)); + Assert.True(actualStyle.UnreadMark); + } + + [Fact] + public void UpdateStyle_OutOfRangeTest() + { + var item = new ListViewItem(); + var style = new ListItemStyle { UnreadMark = false }; + var cache = new ListViewItemCache(10, 10, new[] { (item, style) }); + + var newStyle = style with { UnreadMark = true }; + cache.UpdateStyle(11, newStyle); // 特にエラーは起こさず無視する } } } diff --git a/OpenTween.Tests/TimelineListViewCacheTest.cs b/OpenTween.Tests/TimelineListViewCacheTest.cs index bb6bc201a..83dd3f9ea 100644 --- a/OpenTween.Tests/TimelineListViewCacheTest.cs +++ b/OpenTween.Tests/TimelineListViewCacheTest.cs @@ -77,7 +77,7 @@ public void CreateItem_Test() using var cache = new TimelineListViewCache(listView, tab, new(), theme); var post = this.CreatePost(); - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal("", item.SubItems[0].Text); Assert.Equal("てすと", item.SubItems[1].Text); @@ -100,7 +100,7 @@ public void CreateItem_UnreadTest() var post = this.CreatePost(); post.IsRead = false; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal("★", item.SubItems[5].Text); } @@ -118,7 +118,7 @@ public void CreateItem_UnreadManageDisabledTest() // 未読管理が無効な場合は未読状態に関わらず未読マークを表示しない tab.UnreadManage = false; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal("", item.SubItems[5].Text); } @@ -133,7 +133,7 @@ public void CreateItem_FavoritesTest() var post = this.CreatePost(); post.FavoritedCount = 1; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal("+1", item.SubItems[6].Text); } @@ -149,7 +149,7 @@ public void CreateItem_RetweetTest() post.RetweetedId = 50L; post.RetweetedBy = "hoge"; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal($"test{Environment.NewLine}(RT:hoge)", item.SubItems[4].Text); } @@ -164,7 +164,7 @@ public void CreateItem_DeletedTest() var post = this.CreatePost(); post.IsDeleted = true; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal("(DELETED)", item.SubItems[2].Text); } @@ -179,7 +179,7 @@ public void CreateItem_Font_ReadedTest() var post = this.CreatePost(); post.IsRead = true; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.FontReaded, item.Font); } @@ -194,7 +194,7 @@ public void CreateItem_Font_UnreadTest() var post = this.CreatePost(); post.IsRead = false; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.FontUnread, item.Font); } @@ -212,7 +212,7 @@ public void CreateItem_Font_UnreadStyleDisabledTest() settingCommon.UseUnreadStyle = false; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.FontReaded, item.Font); } @@ -230,7 +230,7 @@ public void CreateItem_Font_UnreadManageDisabledTest() tab.UnreadManage = false; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.FontReaded, item.Font); } @@ -244,7 +244,7 @@ public void CreateItem_ForeColor_Test() var post = this.CreatePost(); - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.ColorRead, item.ForeColor); } @@ -259,7 +259,7 @@ public void CreateItem_ForeColor_FavoritedTest() var post = this.CreatePost(); post.IsFav = true; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.ColorFav, item.ForeColor); } @@ -274,7 +274,7 @@ public void CreateItem_ForeColor_RetweetTest() var post = this.CreatePost(); post.RetweetedId = 100L; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.ColorRetweet, item.ForeColor); } @@ -289,7 +289,7 @@ public void CreateItem_ForeColor_OWLTest() var post = this.CreatePost(); post.IsOwl = true; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.ColorOWL, item.ForeColor); } @@ -307,7 +307,7 @@ public void CreateItem_ForeColor_OWLStyleDisabledTest() settingCommon.OneWayLove = false; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.ColorRead, item.ForeColor); } @@ -327,12 +327,12 @@ public void CreateItem_ForeColor_DMTest() // DM の場合は設定に関わらず ColorOWL を使う settingCommon.OneWayLove = false; - var item = cache.CreateItem(post); + var (item, _) = cache.CreateItem(post); Assert.Equal(theme.ColorOWL, item.ForeColor); } [Fact] - public void JudgeColor_AtToTest() + public void CreateItem_BackColor_AtToTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -340,15 +340,21 @@ public void JudgeColor_AtToTest() using var cache = new TimelineListViewCache(listView, tab, new(), theme); var targetPost = this.CreatePost(); + tab.AddPostQueue(targetPost); var basePost = this.CreatePost(); basePost.InReplyToStatusId = targetPost.StatusId; + tab.AddPostQueue(basePost); - Assert.Equal(theme.ColorAtTo, cache.JudgeColor(basePost, targetPost)); + tab.AddSubmit(); + tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); + + var (item, _) = cache.CreateItem(targetPost); + Assert.Equal(theme.ColorAtTo, item.BackColor); } [Fact] - public void JudgeColor_SelfTest() + public void CreateItem_BackColor_SelfTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -357,14 +363,20 @@ public void JudgeColor_SelfTest() var targetPost = this.CreatePost(); targetPost.IsMe = true; + tab.AddPostQueue(targetPost); var basePost = this.CreatePost(); + tab.AddPostQueue(basePost); + + tab.AddSubmit(); + tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - Assert.Equal(theme.ColorSelf, cache.JudgeColor(basePost, targetPost)); + var (item, _) = cache.CreateItem(targetPost); + Assert.Equal(theme.ColorSelf, item.BackColor); } [Fact] - public void JudgeColor_AtSelfTest() + public void CreateItem_BackColor_AtSelfTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -373,14 +385,20 @@ public void JudgeColor_AtSelfTest() var targetPost = this.CreatePost(); targetPost.IsReply = true; + tab.AddPostQueue(targetPost); var basePost = this.CreatePost(); + tab.AddPostQueue(basePost); - Assert.Equal(theme.ColorAtSelf, cache.JudgeColor(basePost, targetPost)); + tab.AddSubmit(); + tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); + + var (item, _) = cache.CreateItem(targetPost); + Assert.Equal(theme.ColorAtSelf, item.BackColor); } [Fact] - public void JudgeColor_AtFromTargetTest() + public void CreateItem_BackColor_AtFromTargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -388,15 +406,21 @@ public void JudgeColor_AtFromTargetTest() using var cache = new TimelineListViewCache(listView, tab, new(), theme); var targetPost = this.CreatePost(); + tab.AddPostQueue(targetPost); var basePost = this.CreatePost(); basePost.ReplyToList = new() { (targetPost.UserId, targetPost.ScreenName) }; + tab.AddPostQueue(basePost); + + tab.AddSubmit(); + tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - Assert.Equal(theme.ColorAtFromTarget, cache.JudgeColor(basePost, targetPost)); + var (item, _) = cache.CreateItem(targetPost); + Assert.Equal(theme.ColorAtFromTarget, item.BackColor); } [Fact] - public void JudgeColor_AtTargetTest() + public void CreateItem_BackColor_AtTargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -404,15 +428,21 @@ public void JudgeColor_AtTargetTest() using var cache = new TimelineListViewCache(listView, tab, new(), theme); var basePost = this.CreatePost(); + tab.AddPostQueue(basePost); var targetPost = this.CreatePost(); targetPost.ReplyToList = new() { (basePost.UserId, basePost.ScreenName) }; + tab.AddPostQueue(targetPost); - Assert.Equal(theme.ColorAtTarget, cache.JudgeColor(basePost, targetPost)); + tab.AddSubmit(); + tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); + + var (item, _) = cache.CreateItem(targetPost); + Assert.Equal(theme.ColorAtTarget, item.BackColor); } [Fact] - public void JudgeColor_TargetTest() + public void CreateItem_BackColor_TargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -420,15 +450,21 @@ public void JudgeColor_TargetTest() using var cache = new TimelineListViewCache(listView, tab, new(), theme); var targetPost = this.CreatePost(); + tab.AddPostQueue(targetPost); var basePost = this.CreatePost(); basePost.UserId = targetPost.UserId; + tab.AddPostQueue(basePost); + + tab.AddSubmit(); + tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - Assert.Equal(theme.ColorTarget, cache.JudgeColor(basePost, targetPost)); + var (item, _) = cache.CreateItem(targetPost); + Assert.Equal(theme.ColorTarget, item.BackColor); } [Fact] - public void JudgeColor_NormalTest() + public void CreateItem_BackColor_NormalTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -436,9 +472,16 @@ public void JudgeColor_NormalTest() using var cache = new TimelineListViewCache(listView, tab, new(), theme); var targetPost = this.CreatePost(); + tab.AddPostQueue(targetPost); + var basePost = this.CreatePost(); + tab.AddPostQueue(basePost); + + tab.AddSubmit(); + tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - Assert.Equal(theme.ColorListBackcolor, cache.JudgeColor(basePost, targetPost)); + var (item, _) = cache.CreateItem(targetPost); + Assert.Equal(theme.ColorListBackcolor, item.BackColor); } } } diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index 168f84402..bd2adbb73 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -141,7 +141,7 @@ int FilterRange(int index) public void PurgeCache() => Interlocked.Exchange(ref this.listItemCache, null); - internal ListViewItem CreateItem(PostClass post) + internal (ListViewItem Item, ListItemStyle Style) CreateItem(PostClass post) { var mk = new StringBuilder(); @@ -180,90 +180,79 @@ internal ListViewItem CreateItem(PostClass post) } itm.Tag = post; - this.ChangeItemStyleRead(itm, post); - this.ColorizeList(itm, post); + var style = this.DetermineListItemStyle(post); + this.ApplyListItemStyle(itm, style); - return itm; + return (itm, style); } - public void ChangeCacheStyleRead(int index) + public void RefreshStyle(int index) { - var listCache = this.listItemCache; - if (listCache == null) - return; - - // キャッシュに含まれていないアイテムは対象外 - if (!listCache.TryGetValue(index, out var itm)) - return; - var post = this.tab[index]; - this.ChangeItemStyleRead(itm, post); - } + var style = this.DetermineListItemStyle(post); - private void ChangeItemStyleRead(ListViewItem item, PostClass post) - { - var star = this.GetUnreadMark(this.DetermineUnreadMark(post)); - var fnt = this.GetFont(this.DetermineFont(post)); - var cl = this.GetForeColor(this.DetermineForeColor(post)); - - var index = item.Index; - if (index != -1) - this.listView.Update(); + var listCache = this.listItemCache; + if (listCache != null && listCache.TryGetValue(index, out var item, out var currentStyle)) + { + // スタイルに変化がない場合は何もせず終了 + if (currentStyle == style) + return; - if (item.SubItems[5].Text != star) - item.SubItems[5].Text = star; + listCache.UpdateStyle(index, style); + } + else + { + item = this.listView.Items[index]; + } - item.ForeColor = cl; - item.Font = fnt; + // ValidateRectが呼ばれる前に選択色などの描画を済ませておく + this.listView.Update(); - if (index != -1) - this.listView.RefreshItem(index); + this.ApplyListItemStyle(item, style); + this.listView.RefreshItem(index); } - public void ColorizeList() + public void RefreshStyle() { - // Index:更新対象のListviewItem.Index。Colorを返す。 - // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - var basePost = this.tab.AnchorPost ?? this.tab.SelectedPost; - if (basePost == null) - return; - var listCache = this.listItemCache; if (listCache == null) return; - // ValidateRectが呼ばれる前に選択色などの描画を済ませておく - this.listView.Update(); + var updatedIndices = new List(); - foreach (var (listViewItem, index) in listCache.WithIndex()) + foreach (var (_, currentStyle, index) in listCache.WithIndex()) { var post = this.tab[index]; - var backColor = this.JudgeColor(basePost, post); - listViewItem.BackColor = backColor; - this.listView.RefreshItem(index); + var style = this.DetermineListItemStyle(post); + if (currentStyle == style) + continue; + + listCache.UpdateStyle(index, style); + updatedIndices.Add(index); } - } - private void ColorizeList(ListViewItem item, PostClass post) - { - // Index:更新対象のListviewItem.Index。Colorを返す。 - // -1は全キャッシュ。Colorは返さない(ダミーを戻す) - var basePost = this.tab.AnchorPost ?? this.tab.SelectedPost; - if (basePost == null) - return; + // ValidateRectが呼ばれる前に選択色などの描画を済ませておく + this.listView.Update(); - var index = item.Index; - if (index != -1) - this.listView.Update(); + foreach (var index in updatedIndices) + { + if (!listCache.TryGetValue(index, out var item, out var style)) + continue; - item.BackColor = this.JudgeColor(basePost, post); + this.ApplyListItemStyle(item, style); + } - if (index != -1) - this.listView.RefreshItem(index); + updatedIndices.Remove(this.tab.SelectedIndex); + this.listView.RefreshItems(updatedIndices); } - internal Color JudgeColor(PostClass basePost, PostClass targetPost) - => this.GetBackColor(this.DetermineBackColor(basePost, targetPost)); + private void ApplyListItemStyle(ListViewItem item, ListItemStyle style) + { + item.SubItems[5].Text = this.GetUnreadMark(style.UnreadMark); + item.BackColor = this.GetBackColor(style.BackColor); + item.ForeColor = this.GetForeColor(style.ForeColor); + item.Font = this.GetFont(style.Font); + } private string GetUnreadMark(bool unreadMark) => unreadMark ? "★" : ""; @@ -303,10 +292,23 @@ private Font GetFont(ListItemFont font) }; } - private bool DetermineUnreadMark(PostClass post) + private ListItemStyle DetermineListItemStyle(PostClass post) { - // 未読管理していなかったら既読として扱う var unreadManageEnabled = this.tab.UnreadManage && this.settings.UnreadManage; + var useUnreadStyle = unreadManageEnabled && this.settings.UseUnreadStyle; + + var basePost = this.tab.AnchorPost ?? this.tab.SelectedPost; + + return new( + this.DetermineUnreadMark(post, unreadManageEnabled), + this.DetermineBackColor(basePost, post), + this.DetermineForeColor(post, useUnreadStyle), + this.DetermineFont(post, useUnreadStyle) + ); + } + + private bool DetermineUnreadMark(PostClass post, bool unreadManageEnabled) + { if (!unreadManageEnabled) return false; @@ -346,7 +348,7 @@ private ListItemBackColor DetermineBackColor(PostClass? basePost, PostClass post return ListItemBackColor.None; } - private ListItemForeColor DetermineForeColor(PostClass post) + private ListItemForeColor DetermineForeColor(PostClass post, bool useUnreadStyle) { if (post.IsFav) return ListItemForeColor.Fav; @@ -357,20 +359,14 @@ private ListItemForeColor DetermineForeColor(PostClass post) if (post.IsOwl && (post.IsDm || this.settings.OneWayLove)) return ListItemForeColor.OWL; - var unreadManageEnabled = this.tab.UnreadManage && this.settings.UnreadManage; - var useUnreadStyle = unreadManageEnabled && this.settings.UseUnreadStyle; - if (useUnreadStyle && !post.IsRead) return ListItemForeColor.Unread; return ListItemForeColor.None; } - private ListItemFont DetermineFont(PostClass post) + private ListItemFont DetermineFont(PostClass post, bool useUnreadStyle) { - var unreadManageEnabled = this.tab.UnreadManage && this.settings.UnreadManage; - var useUnreadStyle = unreadManageEnabled && this.settings.UseUnreadStyle; - if (useUnreadStyle && !post.IsRead) return ListItemFont.Unread; @@ -396,7 +392,7 @@ private void ListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEven var listCache = this.listItemCache; if (listCache != null) { - if (listCache.TryGetValue(e.ItemIndex, out var item)) + if (listCache.TryGetValue(e.ItemIndex, out var item, out _)) { e.Item = item; return; @@ -406,7 +402,7 @@ private void ListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEven // A cache miss, so create a new ListViewItem and pass it back. try { - e.Item = this.CreateItem(this.tab[e.ItemIndex]); + e.Item = this.CreateItem(this.tab[e.ItemIndex]).Item; } catch (Exception) { @@ -456,6 +452,13 @@ public enum ListItemFont Unread, } + public readonly record struct ListItemStyle( + bool UnreadMark, + ListItemBackColor BackColor, + ListItemForeColor ForeColor, + ListItemFont Font + ); + public class ListViewItemCache { /// キャッシュする範囲の開始インデックス @@ -464,14 +467,14 @@ public class ListViewItemCache /// キャッシュする範囲の終了インデックス public int EndIndex { get; } - /// キャッシュされた範囲に対応する の配列 - public ListViewItem[] Cache { get; } + /// キャッシュされた範囲に対応する の配列 + public (ListViewItem, ListItemStyle)[] Cache { get; } /// キャッシュされたアイテムの件数 public int Count => this.EndIndex - this.StartIndex + 1; - public ListViewItemCache(int startIndex, int endIndex, ListViewItem[] cache) + public ListViewItemCache(int startIndex, int endIndex, (ListViewItem, ListItemStyle)[] cache) { if (!IsCacheSizeValid(startIndex, endIndex, cache)) throw new ArgumentException("Cache size mismatch", nameof(cache)); @@ -493,24 +496,33 @@ public bool IsSupersetOf(int rangeStart, int rangeEnd) /// 指定されたインデックスの をキャッシュから取得することを試みます /// 取得に成功すれば true、それ以外は false - public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item) + public bool TryGetValue(int index, [NotNullWhen(true)] out ListViewItem? item, out ListItemStyle style) { if (this.Contains(index)) { - item = this.Cache[index - this.StartIndex]; + (item, style) = this.Cache[index - this.StartIndex]; return true; } else { item = null; + style = default; return false; } } - public IEnumerable<(ListViewItem Item, int Index)> WithIndex() + public IEnumerable<(ListViewItem Item, ListItemStyle Stype, int Index)> WithIndex() { - foreach (var (item, index) in this.Cache.WithIndex()) - yield return (item, index + this.StartIndex); + foreach (var ((item, style), index) in this.Cache.WithIndex()) + yield return (item, style, index + this.StartIndex); + } + + public void UpdateStyle(int index, ListItemStyle style) + { + if (!this.Contains(index)) + return; + + this.Cache[index - this.StartIndex].Item2 = style; } private static bool IsCacheSizeValid(int startIndex, int endIndex, T[] cache) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 58cd25bc4..ae0215e2b 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1353,10 +1353,7 @@ private async void MyList_SelectedIndexChanged(object sender, EventArgs e) var post = this.CurrentPost!; this.statuses.SetReadAllTab(post.StatusId, read: true); - // キャッシュの書き換え - this.listCache?.ChangeCacheStyleRead(index); // 既読へ(フォント、文字色) - - this.listCache?.ColorizeList(); + this.listCache?.RefreshStyle(); await this.selectionDebouncer.Call(); } @@ -1726,7 +1723,7 @@ await this.tw.Api.FavoritesCreate(post.RetweetedId ?? post.StatusId) { var idx = tab.IndexOf(statusId); if (idx != -1) - this.listCache?.ChangeCacheStyleRead(idx); + this.listCache?.RefreshStyle(idx); } var currentPost = this.CurrentPost; @@ -1836,7 +1833,7 @@ await this.tw.Api.FavoritesDestroy(post.RetweetedId ?? post.StatusId) { var idx = tab.IndexOf(statusId); if (idx != -1) - this.listCache?.ChangeCacheStyleRead(idx); + this.listCache?.RefreshStyle(idx); } } @@ -2688,9 +2685,8 @@ private void ReadedStripMenuItem_Click(object sender, EventArgs e) { this.statuses.SetReadAllTab(statusId, read: true); var idx = tab.IndexOf(statusId); - this.listCache?.ChangeCacheStyleRead(idx); + this.listCache?.RefreshStyle(idx); } - this.listCache?.ColorizeList(); } if (this.settings.Common.TabIconDisp) { @@ -2716,9 +2712,8 @@ private void UnreadStripMenuItem_Click(object sender, EventArgs e) { this.statuses.SetReadAllTab(statusId, read: false); var idx = tab.IndexOf(statusId); - this.listCache?.ChangeCacheStyleRead(idx); + this.listCache?.RefreshStyle(idx); } - this.listCache?.ColorizeList(); } if (this.settings.Common.TabIconDisp) { From f11c3715bedf55859499ee54c2e8811712e47dd8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 26 Apr 2022 02:07:39 +0900 Subject: [PATCH 192/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E6=8F=8F=E7=94=BB=E6=99=82=E3=81=AB=E3=82=B9=E3=82=BF?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=81=AE=E6=83=85=E5=A0=B1=E3=82=92TimelineL?= =?UTF-8?q?istViewCache=E3=81=8B=E3=82=89=E7=9B=B4=E6=8E=A5=E5=8F=96?= =?UTF-8?q?=E5=BE=97=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TimelineListViewCacheTest.cs | 140 ++++++++----------- OpenTween/TimelineListViewCache.cs | 60 ++------ OpenTween/TimelineListViewDrawer.cs | 101 +++++++++---- OpenTween/Tween.cs | 4 +- 4 files changed, 148 insertions(+), 157 deletions(-) diff --git a/OpenTween.Tests/TimelineListViewCacheTest.cs b/OpenTween.Tests/TimelineListViewCacheTest.cs index 83dd3f9ea..8c0112511 100644 --- a/OpenTween.Tests/TimelineListViewCacheTest.cs +++ b/OpenTween.Tests/TimelineListViewCacheTest.cs @@ -51,8 +51,7 @@ public void UpdateListSize_Test() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); Assert.Equal(0, listView.VirtualListSize); Assert.False(cache.IsListSizeMismatched); @@ -73,8 +72,7 @@ public void CreateItem_Test() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); var (item, _) = cache.CreateItem(post); @@ -94,8 +92,7 @@ public void CreateItem_UnreadTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.IsRead = false; @@ -109,8 +106,7 @@ public void CreateItem_UnreadManageDisabledTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.IsRead = false; @@ -127,8 +123,7 @@ public void CreateItem_FavoritesTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.FavoritedCount = 1; @@ -142,8 +137,7 @@ public void CreateItem_RetweetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.RetweetedId = 50L; @@ -158,8 +152,7 @@ public void CreateItem_DeletedTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.IsDeleted = true; @@ -173,14 +166,13 @@ public void CreateItem_Font_ReadedTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.IsRead = true; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.FontReaded, item.Font); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemFont.Readed, style.Font); } [Fact] @@ -188,14 +180,13 @@ public void CreateItem_Font_UnreadTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.IsRead = false; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.FontUnread, item.Font); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemFont.Unread, style.Font); } [Fact] @@ -204,16 +195,15 @@ public void CreateItem_Font_UnreadStyleDisabledTest() var tab = new PublicSearchTabModel("tab"); var settingCommon = new SettingCommon(); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, settingCommon, theme); + using var cache = new TimelineListViewCache(listView, tab, settingCommon); var post = this.CreatePost(); post.IsRead = false; settingCommon.UseUnreadStyle = false; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.FontReaded, item.Font); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemFont.Readed, style.Font); } [Fact] @@ -222,16 +212,15 @@ public void CreateItem_Font_UnreadManageDisabledTest() var tab = new PublicSearchTabModel("tab"); var settingCommon = new SettingCommon(); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, settingCommon, theme); + using var cache = new TimelineListViewCache(listView, tab, settingCommon); var post = this.CreatePost(); post.IsRead = false; tab.UnreadManage = false; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.FontReaded, item.Font); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemFont.Readed, style.Font); } [Fact] @@ -239,13 +228,12 @@ public void CreateItem_ForeColor_Test() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.ColorRead, item.ForeColor); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemForeColor.None, style.ForeColor); } [Fact] @@ -253,14 +241,13 @@ public void CreateItem_ForeColor_FavoritedTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.IsFav = true; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.ColorFav, item.ForeColor); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemForeColor.Fav, style.ForeColor); } [Fact] @@ -268,14 +255,13 @@ public void CreateItem_ForeColor_RetweetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.RetweetedId = 100L; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.ColorRetweet, item.ForeColor); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemForeColor.Retweet, style.ForeColor); } [Fact] @@ -283,14 +269,13 @@ public void CreateItem_ForeColor_OWLTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); post.IsOwl = true; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.ColorOWL, item.ForeColor); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemForeColor.OWL, style.ForeColor); } [Fact] @@ -299,16 +284,15 @@ public void CreateItem_ForeColor_OWLStyleDisabledTest() var tab = new PublicSearchTabModel("tab"); var settingCommon = new SettingCommon(); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, settingCommon, theme); + using var cache = new TimelineListViewCache(listView, tab, settingCommon); var post = this.CreatePost(); post.IsOwl = true; settingCommon.OneWayLove = false; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.ColorRead, item.ForeColor); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemForeColor.None, style.ForeColor); } [Fact] @@ -317,8 +301,7 @@ public void CreateItem_ForeColor_DMTest() var tab = new PublicSearchTabModel("tab"); var settingCommon = new SettingCommon(); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, settingCommon, theme); + using var cache = new TimelineListViewCache(listView, tab, settingCommon); var post = this.CreatePost(); post.IsDm = true; @@ -327,8 +310,8 @@ public void CreateItem_ForeColor_DMTest() // DM の場合は設定に関わらず ColorOWL を使う settingCommon.OneWayLove = false; - var (item, _) = cache.CreateItem(post); - Assert.Equal(theme.ColorOWL, item.ForeColor); + var (_, style) = cache.CreateItem(post); + Assert.Equal(ListItemForeColor.OWL, style.ForeColor); } [Fact] @@ -336,8 +319,7 @@ public void CreateItem_BackColor_AtToTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var targetPost = this.CreatePost(); tab.AddPostQueue(targetPost); @@ -349,8 +331,8 @@ public void CreateItem_BackColor_AtToTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (item, _) = cache.CreateItem(targetPost); - Assert.Equal(theme.ColorAtTo, item.BackColor); + var (_, style) = cache.CreateItem(targetPost); + Assert.Equal(ListItemBackColor.AtTo, style.BackColor); } [Fact] @@ -358,8 +340,7 @@ public void CreateItem_BackColor_SelfTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var targetPost = this.CreatePost(); targetPost.IsMe = true; @@ -371,8 +352,8 @@ public void CreateItem_BackColor_SelfTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (item, _) = cache.CreateItem(targetPost); - Assert.Equal(theme.ColorSelf, item.BackColor); + var (_, style) = cache.CreateItem(targetPost); + Assert.Equal(ListItemBackColor.Self, style.BackColor); } [Fact] @@ -380,8 +361,7 @@ public void CreateItem_BackColor_AtSelfTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var targetPost = this.CreatePost(); targetPost.IsReply = true; @@ -393,8 +373,8 @@ public void CreateItem_BackColor_AtSelfTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (item, _) = cache.CreateItem(targetPost); - Assert.Equal(theme.ColorAtSelf, item.BackColor); + var (_, style) = cache.CreateItem(targetPost); + Assert.Equal(ListItemBackColor.AtSelf, style.BackColor); } [Fact] @@ -402,8 +382,7 @@ public void CreateItem_BackColor_AtFromTargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var targetPost = this.CreatePost(); tab.AddPostQueue(targetPost); @@ -415,8 +394,8 @@ public void CreateItem_BackColor_AtFromTargetTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (item, _) = cache.CreateItem(targetPost); - Assert.Equal(theme.ColorAtFromTarget, item.BackColor); + var (_, style) = cache.CreateItem(targetPost); + Assert.Equal(ListItemBackColor.AtFromTarget, style.BackColor); } [Fact] @@ -424,8 +403,7 @@ public void CreateItem_BackColor_AtTargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var basePost = this.CreatePost(); tab.AddPostQueue(basePost); @@ -437,8 +415,8 @@ public void CreateItem_BackColor_AtTargetTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (item, _) = cache.CreateItem(targetPost); - Assert.Equal(theme.ColorAtTarget, item.BackColor); + var (_, style) = cache.CreateItem(targetPost); + Assert.Equal(ListItemBackColor.AtTarget, style.BackColor); } [Fact] @@ -446,8 +424,7 @@ public void CreateItem_BackColor_TargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var targetPost = this.CreatePost(); tab.AddPostQueue(targetPost); @@ -459,8 +436,8 @@ public void CreateItem_BackColor_TargetTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (item, _) = cache.CreateItem(targetPost); - Assert.Equal(theme.ColorTarget, item.BackColor); + var (_, style) = cache.CreateItem(targetPost); + Assert.Equal(ListItemBackColor.Target, style.BackColor); } [Fact] @@ -468,8 +445,7 @@ public void CreateItem_BackColor_NormalTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); - using var theme = new ThemeManager(new()); - using var cache = new TimelineListViewCache(listView, tab, new(), theme); + using var cache = new TimelineListViewCache(listView, tab, new()); var targetPost = this.CreatePost(); tab.AddPostQueue(targetPost); @@ -480,8 +456,8 @@ public void CreateItem_BackColor_NormalTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (item, _) = cache.CreateItem(targetPost); - Assert.Equal(theme.ColorListBackcolor, item.BackColor); + var (_, style) = cache.CreateItem(targetPost); + Assert.Equal(ListItemBackColor.None, style.BackColor); } } } diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index bd2adbb73..b33a78ad1 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -29,7 +29,6 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Drawing; using System.Linq; using System.Text; using System.Threading; @@ -43,8 +42,6 @@ public sealed class TimelineListViewCache : IDisposable { public bool IsDisposed { get; private set; } = false; - public ThemeManager Theme { get; set; } - public bool IsListSizeMismatched => this.listView.VirtualListSize != this.tab.AllCount; @@ -65,14 +62,12 @@ public bool IsListSizeMismatched public TimelineListViewCache( DetailsListView listView, TabModel tab, - SettingCommon settings, - ThemeManager theme + SettingCommon settings ) { this.listView = listView; this.tab = tab; this.settings = settings; - this.Theme = theme; this.RegisterHandlers(); this.listView.VirtualMode = true; @@ -246,51 +241,24 @@ public void RefreshStyle() this.listView.RefreshItems(updatedIndices); } - private void ApplyListItemStyle(ListViewItem item, ListItemStyle style) + public ListItemStyle GetStyle(int index) { - item.SubItems[5].Text = this.GetUnreadMark(style.UnreadMark); - item.BackColor = this.GetBackColor(style.BackColor); - item.ForeColor = this.GetForeColor(style.ForeColor); - item.Font = this.GetFont(style.Font); - } - - private string GetUnreadMark(bool unreadMark) - => unreadMark ? "★" : ""; - - private Color GetBackColor(ListItemBackColor backColor) - { - return backColor switch + var listCache = this.listItemCache; + if (listCache != null) { - ListItemBackColor.Self => this.Theme.ColorSelf, - ListItemBackColor.AtSelf => this.Theme.ColorAtSelf, - ListItemBackColor.Target => this.Theme.ColorTarget, - ListItemBackColor.AtTarget => this.Theme.ColorAtTarget, - ListItemBackColor.AtFromTarget => this.Theme.ColorAtFromTarget, - ListItemBackColor.AtTo => this.Theme.ColorAtTo, - _ => this.Theme.ColorListBackcolor, - }; - } + if (listCache.TryGetValue(index, out _, out var style)) + return style; + } - private Color GetForeColor(ListItemForeColor foreColor) - { - return foreColor switch - { - ListItemForeColor.Fav => this.Theme.ColorFav, - ListItemForeColor.Retweet => this.Theme.ColorRetweet, - ListItemForeColor.OWL => this.Theme.ColorOWL, - ListItemForeColor.Unread => this.Theme.ColorUnread, - _ => this.Theme.ColorRead, - }; + var post = this.tab[index]; + return this.DetermineListItemStyle(post); } - private Font GetFont(ListItemFont font) - { - return font switch - { - ListItemFont.Unread => this.Theme.FontUnread, - _ => this.Theme.FontReaded, - }; - } + private void ApplyListItemStyle(ListViewItem item, ListItemStyle style) + => item.SubItems[5].Text = this.GetUnreadMark(style.UnreadMark); + + private string GetUnreadMark(bool unreadMark) + => unreadMark ? "★" : ""; private ListItemStyle DetermineListItemStyle(PostClass post) { diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs index 389b123bd..a84b199f6 100644 --- a/OpenTween/TimelineListViewDrawer.cs +++ b/OpenTween/TimelineListViewDrawer.cs @@ -69,14 +69,22 @@ private int IconSizeNumeric private readonly DetailsListView listView; private readonly TabModel tab; + private readonly TimelineListViewCache listViewCache; private readonly ImageCache iconCache; private readonly ImageList listViewImageList = new(); // ListViewItemの高さ変更用 private MyCommon.IconSizes iconSize; - public TimelineListViewDrawer(DetailsListView listView, TabModel tab, ImageCache iconCache, ThemeManager theme) + public TimelineListViewDrawer( + DetailsListView listView, + TabModel tab, + TimelineListViewCache listViewCache, + ImageCache iconCache, + ThemeManager theme + ) { this.listView = listView; this.tab = tab; + this.listViewCache = listViewCache; this.iconCache = iconCache; this.Theme = theme; @@ -219,28 +227,61 @@ private Icon GetPostStateIcon(int stateIndex) }; } + private Brush GetBackColorBrush(ListItemBackColor backColor) + { + return backColor switch + { + ListItemBackColor.Self => this.Theme.BrushSelf, + ListItemBackColor.AtSelf => this.Theme.BrushAtSelf, + ListItemBackColor.Target => this.Theme.BrushTarget, + ListItemBackColor.AtTarget => this.Theme.BrushAtTarget, + ListItemBackColor.AtFromTarget => this.Theme.BrushAtFromTarget, + ListItemBackColor.AtTo => this.Theme.BrushAtTo, + _ => this.Theme.BrushListBackcolor, + }; + } + + private Color GetForeColor(ListItemForeColor foreColor) + { + return foreColor switch + { + ListItemForeColor.Fav => this.Theme.ColorFav, + ListItemForeColor.Retweet => this.Theme.ColorRetweet, + ListItemForeColor.OWL => this.Theme.ColorOWL, + ListItemForeColor.Unread => this.Theme.ColorUnread, + _ => this.Theme.ColorRead, + }; + } + + private Font GetFont(ListItemFont font) + { + return font switch + { + ListItemFont.Unread => this.Theme.FontUnread, + _ => this.Theme.FontReaded, + }; + } + + private Font GetFontBold(ListItemFont font) + { + return font switch + { + ListItemFont.Unread => this.Theme.FontUnreadBold, + _ => this.Theme.FontReadedBold, + }; + } + private void ListView_DrawItem(object sender, DrawListViewItemEventArgs e) { if (e.State == 0) return; e.DrawDefault = false; + var style = this.listViewCache.GetStyle(e.ItemIndex); + Brush brs2; if (!e.Item.Selected) // e.ItemStateでうまく判定できない??? { - if (e.Item.BackColor == this.Theme.ColorSelf) - brs2 = this.Theme.BrushSelf; - else if (e.Item.BackColor == this.Theme.ColorAtSelf) - brs2 = this.Theme.BrushAtSelf; - else if (e.Item.BackColor == this.Theme.ColorTarget) - brs2 = this.Theme.BrushTarget; - else if (e.Item.BackColor == this.Theme.ColorAtTarget) - brs2 = this.Theme.BrushAtTarget; - else if (e.Item.BackColor == this.Theme.ColorAtFromTarget) - brs2 = this.Theme.BrushAtFromTarget; - else if (e.Item.BackColor == this.Theme.ColorAtTo) - brs2 = this.Theme.BrushAtTo; - else - brs2 = this.Theme.BrushListBackcolor; + brs2 = this.GetBackColorBrush(style.BackColor); } else { @@ -263,10 +304,12 @@ private void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) { // アイコン以外の列 var post = (PostClass)e.Item.Tag; + var style = this.listViewCache.GetStyle(e.ItemIndex); + var font = this.GetFont(style.Font); RectangleF rct = e.Bounds; rct.Width = e.Header.Width; - var fontHeight = e.Item.Font.Height; + var fontHeight = font.Height; if (this.Use2ColumnsMode) { rct.Y += fontHeight; @@ -291,9 +334,17 @@ private void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) if (rct.Width > 0) { - var color = (!e.Item.Selected) ? e.Item.ForeColor : // 選択されていない行 - ((Control)sender).Focused ? this.Theme.ColorHighLight : // 選択中の行 - this.Theme.ColorUnread; + Color color; + if (e.Item.Selected) + { + color = ((Control)sender).Focused + ? this.Theme.ColorHighLight + : this.Theme.ColorUnread; + } + else + { + color = this.GetForeColor(style.ForeColor); + } if (this.Use2ColumnsMode) { @@ -301,11 +352,7 @@ private void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) rctB.Width = e.Header.Width; rctB.Height = fontHeight; - Font fontBold; - if (e.Item.Font.Equals(this.Theme.FontUnread)) - fontBold = this.Theme.FontUnreadBold; - else - fontBold = this.Theme.FontReadedBold; + var fontBold = this.GetFontBold(style.Font); var formatFlags1 = TextFormatFlags.WordBreak | TextFormatFlags.EndEllipsis | @@ -315,7 +362,7 @@ private void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) TextRenderer.DrawText( e.Graphics, post.IsDeleted ? "(DELETED)" : post.TextSingleLine, - e.Item.Font, + font, Rectangle.Round(rct), color, formatFlags1); @@ -352,7 +399,7 @@ private void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) TextRenderer.DrawText( e.Graphics, text, - e.Item.Font, + font, Rectangle.Round(rct), color, formatFlags); @@ -367,7 +414,7 @@ private void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) TextRenderer.DrawText( e.Graphics, text, - e.Item.Font, + font, Rectangle.Round(rct), color, formatFlags); diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index ae0215e2b..a89c69581 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -8103,11 +8103,11 @@ private void InitializeTimelineListView() var listView = this.CurrentListView; var tab = this.CurrentTab; - var newCache = new TimelineListViewCache(listView, tab, this.settings.Common, this.themeManager); + var newCache = new TimelineListViewCache(listView, tab, this.settings.Common); (this.listCache, var oldCache) = (newCache, this.listCache); oldCache?.Dispose(); - var newDrawer = new TimelineListViewDrawer(listView, tab, this.iconCache, this.themeManager) + var newDrawer = new TimelineListViewDrawer(listView, tab, this.listCache, this.iconCache, this.themeManager) { IconSize = this.settings.Common.IconSize, }; From db60f0d87c62ee902e67e14fae6b2d3ac3d65a62 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 26 Apr 2022 03:26:45 +0900 Subject: [PATCH 193/402] =?UTF-8?q?ListViewItem=E6=8F=8F=E7=94=BB=E6=99=82?= =?UTF-8?q?=E3=81=ABTag=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=9B=E3=81=9ATabMod?= =?UTF-8?q?el=E3=81=8B=E3=82=89PostClass=E3=82=92=E5=8F=96=E5=BE=97?= =?UTF-8?q?=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/TimelineListViewCache.cs | 1 - OpenTween/TimelineListViewDrawer.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index b33a78ad1..dce649955 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -173,7 +173,6 @@ public void PurgeCache() }; itm = new ListViewItem(sitem); } - itm.Tag = post; var style = this.DetermineListItemStyle(post); this.ApplyListItemStyle(itm, style); diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs index a84b199f6..252b35583 100644 --- a/OpenTween/TimelineListViewDrawer.cs +++ b/OpenTween/TimelineListViewDrawer.cs @@ -303,7 +303,7 @@ private void ListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e) if (e.ColumnIndex > 0) { // アイコン以外の列 - var post = (PostClass)e.Item.Tag; + var post = this.tab[e.ItemIndex]; var style = this.listViewCache.GetStyle(e.ItemIndex); var font = this.GetFont(style.Font); From 91f379c6094c3d611c51ec3494053f2a31381d3c Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 26 Apr 2022 04:05:23 +0900 Subject: [PATCH 194/402] =?UTF-8?q?TimelineListViewCache.GetItem=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/TimelineListViewCache.cs | 37 +++++++++++------------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index dce649955..f2af7e02f 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -240,6 +240,19 @@ public void RefreshStyle() this.listView.RefreshItems(updatedIndices); } + public ListViewItem GetItem(int index) + { + var listCache = this.listItemCache; + if (listCache != null) + { + if (listCache.TryGetValue(index, out var item, out _)) + return item; + } + + var post = this.tab[index]; + return this.CreateItem(post).Item; + } + public ListItemStyle GetStyle(int index) { var listCache = this.listItemCache; @@ -355,29 +368,7 @@ private void ListView_CacheVirtualItems(object sender, CacheVirtualItemsEventArg } private void ListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) - { - var listCache = this.listItemCache; - if (listCache != null) - { - if (listCache.TryGetValue(e.ItemIndex, out var item, out _)) - { - e.Item = item; - return; - } - } - - // A cache miss, so create a new ListViewItem and pass it back. - try - { - e.Item = this.CreateItem(this.tab[e.ItemIndex]).Item; - } - catch (Exception) - { - // 不正な要求に対する間に合わせの応答 - string[] sitem = { "", "", "", "", "", "", "", "" }; - e.Item = new ListViewItem(sitem); - } - } + => e.Item = this.GetItem(e.ItemIndex); public void Dispose() { From 755a32a02c6f054b6c2e84bf7297b3e3847b0281 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 22 May 2022 02:33:25 +0900 Subject: [PATCH 195/402] =?UTF-8?q?TimelineListViewCache=E3=81=AE=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=81=ABGetItem/GetStyle=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TimelineListViewCacheTest.cs | 144 ++++++++++++------- OpenTween/TimelineListViewCache.cs | 2 +- 2 files changed, 97 insertions(+), 49 deletions(-) diff --git a/OpenTween.Tests/TimelineListViewCacheTest.cs b/OpenTween.Tests/TimelineListViewCacheTest.cs index 8c0112511..764bc37aa 100644 --- a/OpenTween.Tests/TimelineListViewCacheTest.cs +++ b/OpenTween.Tests/TimelineListViewCacheTest.cs @@ -68,14 +68,17 @@ public void UpdateListSize_Test() } [Fact] - public void CreateItem_Test() + public void GetItem_Test() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); using var cache = new TimelineListViewCache(listView, tab, new()); var post = this.CreatePost(); - var (item, _) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var item = cache.GetItem(0); Assert.Equal("", item.SubItems[0].Text); Assert.Equal("てすと", item.SubItems[1].Text); @@ -88,7 +91,7 @@ public void CreateItem_Test() } [Fact] - public void CreateItem_UnreadTest() + public void GetItem_UnreadTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -97,29 +100,35 @@ public void CreateItem_UnreadTest() var post = this.CreatePost(); post.IsRead = false; - var (item, _) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var item = cache.GetItem(0); Assert.Equal("★", item.SubItems[5].Text); } [Fact] - public void CreateItem_UnreadManageDisabledTest() + public void GetItem_UnreadManageDisabledTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); using var cache = new TimelineListViewCache(listView, tab, new()); + // 未読管理が無効な場合は未読状態に関わらず未読マークを表示しない + tab.UnreadManage = false; + var post = this.CreatePost(); post.IsRead = false; - // 未読管理が無効な場合は未読状態に関わらず未読マークを表示しない - tab.UnreadManage = false; + tab.AddPostQueue(post); + tab.AddSubmit(); - var (item, _) = cache.CreateItem(post); + var item = cache.GetItem(0); Assert.Equal("", item.SubItems[5].Text); } [Fact] - public void CreateItem_FavoritesTest() + public void GetItem_FavoritesTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -128,12 +137,15 @@ public void CreateItem_FavoritesTest() var post = this.CreatePost(); post.FavoritedCount = 1; - var (item, _) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var item = cache.GetItem(0); Assert.Equal("+1", item.SubItems[6].Text); } [Fact] - public void CreateItem_RetweetTest() + public void GetItem_RetweetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -143,12 +155,15 @@ public void CreateItem_RetweetTest() post.RetweetedId = 50L; post.RetweetedBy = "hoge"; - var (item, _) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var item = cache.GetItem(0); Assert.Equal($"test{Environment.NewLine}(RT:hoge)", item.SubItems[4].Text); } [Fact] - public void CreateItem_DeletedTest() + public void GetItem_DeletedTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -157,12 +172,15 @@ public void CreateItem_DeletedTest() var post = this.CreatePost(); post.IsDeleted = true; - var (item, _) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var item = cache.GetItem(0); Assert.Equal("(DELETED)", item.SubItems[2].Text); } [Fact] - public void CreateItem_Font_ReadedTest() + public void GetStyle_Font_ReadedTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -171,12 +189,15 @@ public void CreateItem_Font_ReadedTest() var post = this.CreatePost(); post.IsRead = true; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemFont.Readed, style.Font); } [Fact] - public void CreateItem_Font_UnreadTest() + public void GetStyle_Font_UnreadTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -185,12 +206,15 @@ public void CreateItem_Font_UnreadTest() var post = this.CreatePost(); post.IsRead = false; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemFont.Unread, style.Font); } [Fact] - public void CreateItem_Font_UnreadStyleDisabledTest() + public void GetStyle_Font_UnreadStyleDisabledTest() { var tab = new PublicSearchTabModel("tab"); var settingCommon = new SettingCommon(); @@ -202,12 +226,15 @@ public void CreateItem_Font_UnreadStyleDisabledTest() settingCommon.UseUnreadStyle = false; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemFont.Readed, style.Font); } [Fact] - public void CreateItem_Font_UnreadManageDisabledTest() + public void GetStyle_Font_UnreadManageDisabledTest() { var tab = new PublicSearchTabModel("tab"); var settingCommon = new SettingCommon(); @@ -219,12 +246,15 @@ public void CreateItem_Font_UnreadManageDisabledTest() tab.UnreadManage = false; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemFont.Readed, style.Font); } [Fact] - public void CreateItem_ForeColor_Test() + public void GetStyleItem_ForeColor_Test() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -232,12 +262,15 @@ public void CreateItem_ForeColor_Test() var post = this.CreatePost(); - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemForeColor.None, style.ForeColor); } [Fact] - public void CreateItem_ForeColor_FavoritedTest() + public void GetStyle_ForeColor_FavoritedTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -246,12 +279,15 @@ public void CreateItem_ForeColor_FavoritedTest() var post = this.CreatePost(); post.IsFav = true; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemForeColor.Fav, style.ForeColor); } [Fact] - public void CreateItem_ForeColor_RetweetTest() + public void GetStyle_ForeColor_RetweetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -260,12 +296,15 @@ public void CreateItem_ForeColor_RetweetTest() var post = this.CreatePost(); post.RetweetedId = 100L; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemForeColor.Retweet, style.ForeColor); } [Fact] - public void CreateItem_ForeColor_OWLTest() + public void GetStyle_ForeColor_OWLTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -274,12 +313,15 @@ public void CreateItem_ForeColor_OWLTest() var post = this.CreatePost(); post.IsOwl = true; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemForeColor.OWL, style.ForeColor); } [Fact] - public void CreateItem_ForeColor_OWLStyleDisabledTest() + public void GetStyle_ForeColor_OWLStyleDisabledTest() { var tab = new PublicSearchTabModel("tab"); var settingCommon = new SettingCommon(); @@ -291,12 +333,15 @@ public void CreateItem_ForeColor_OWLStyleDisabledTest() settingCommon.OneWayLove = false; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemForeColor.None, style.ForeColor); } [Fact] - public void CreateItem_ForeColor_DMTest() + public void GetStyle_ForeColor_DMTest() { var tab = new PublicSearchTabModel("tab"); var settingCommon = new SettingCommon(); @@ -310,12 +355,15 @@ public void CreateItem_ForeColor_DMTest() // DM の場合は設定に関わらず ColorOWL を使う settingCommon.OneWayLove = false; - var (_, style) = cache.CreateItem(post); + tab.AddPostQueue(post); + tab.AddSubmit(); + + var style = cache.GetStyle(0); Assert.Equal(ListItemForeColor.OWL, style.ForeColor); } [Fact] - public void CreateItem_BackColor_AtToTest() + public void GetStyle_BackColor_AtToTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -331,12 +379,12 @@ public void CreateItem_BackColor_AtToTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (_, style) = cache.CreateItem(targetPost); + var style = cache.GetStyle(tab.IndexOf(targetPost.StatusId)); Assert.Equal(ListItemBackColor.AtTo, style.BackColor); } [Fact] - public void CreateItem_BackColor_SelfTest() + public void GetStyle_BackColor_SelfTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -352,12 +400,12 @@ public void CreateItem_BackColor_SelfTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (_, style) = cache.CreateItem(targetPost); + var style = cache.GetStyle(tab.IndexOf(targetPost.StatusId)); Assert.Equal(ListItemBackColor.Self, style.BackColor); } [Fact] - public void CreateItem_BackColor_AtSelfTest() + public void GetStyle_BackColor_AtSelfTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -373,12 +421,12 @@ public void CreateItem_BackColor_AtSelfTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (_, style) = cache.CreateItem(targetPost); + var style = cache.GetStyle(tab.IndexOf(targetPost.StatusId)); Assert.Equal(ListItemBackColor.AtSelf, style.BackColor); } [Fact] - public void CreateItem_BackColor_AtFromTargetTest() + public void GetStyle_BackColor_AtFromTargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -394,12 +442,12 @@ public void CreateItem_BackColor_AtFromTargetTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (_, style) = cache.CreateItem(targetPost); + var style = cache.GetStyle(tab.IndexOf(targetPost.StatusId)); Assert.Equal(ListItemBackColor.AtFromTarget, style.BackColor); } [Fact] - public void CreateItem_BackColor_AtTargetTest() + public void GetStyle_BackColor_AtTargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -415,12 +463,12 @@ public void CreateItem_BackColor_AtTargetTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (_, style) = cache.CreateItem(targetPost); + var style = cache.GetStyle(tab.IndexOf(targetPost.StatusId)); Assert.Equal(ListItemBackColor.AtTarget, style.BackColor); } [Fact] - public void CreateItem_BackColor_TargetTest() + public void GetStyle_BackColor_TargetTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -436,12 +484,12 @@ public void CreateItem_BackColor_TargetTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (_, style) = cache.CreateItem(targetPost); + var style = cache.GetStyle(tab.IndexOf(targetPost.StatusId)); Assert.Equal(ListItemBackColor.Target, style.BackColor); } [Fact] - public void CreateItem_BackColor_NormalTest() + public void GetStyle_BackColor_NormalTest() { var tab = new PublicSearchTabModel("tab"); using var listView = new DetailsListView(); @@ -456,7 +504,7 @@ public void CreateItem_BackColor_NormalTest() tab.AddSubmit(); tab.SelectPosts(new[] { tab.IndexOf(basePost.StatusId) }); - var (_, style) = cache.CreateItem(targetPost); + var style = cache.GetStyle(tab.IndexOf(targetPost.StatusId)); Assert.Equal(ListItemBackColor.None, style.BackColor); } } diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index f2af7e02f..c3fd7d453 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -136,7 +136,7 @@ int FilterRange(int index) public void PurgeCache() => Interlocked.Exchange(ref this.listItemCache, null); - internal (ListViewItem Item, ListItemStyle Style) CreateItem(PostClass post) + private (ListViewItem Item, ListItemStyle Style) CreateItem(PostClass post) { var mk = new StringBuilder(); From 6f578122a1cce7c7d7012306d6f7a97184e4d1ed Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 22 May 2022 03:08:55 +0900 Subject: [PATCH 196/402] =?UTF-8?q?TimelineListViewCache=E3=81=AE=E3=82=AD?= =?UTF-8?q?=E3=83=A3=E3=83=83=E3=82=B7=E3=83=A5=E7=8A=B6=E6=85=8B=E3=81=AB?= =?UTF-8?q?=E9=96=A2=E3=81=99=E3=82=8B=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TimelineListViewCacheTest.cs | 40 ++++++++++++++++++++ OpenTween/TimelineListViewCache.cs | 2 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/OpenTween.Tests/TimelineListViewCacheTest.cs b/OpenTween.Tests/TimelineListViewCacheTest.cs index 764bc37aa..cd701866d 100644 --- a/OpenTween.Tests/TimelineListViewCacheTest.cs +++ b/OpenTween.Tests/TimelineListViewCacheTest.cs @@ -179,6 +179,26 @@ public void GetItem_DeletedTest() Assert.Equal("(DELETED)", item.SubItems[2].Text); } + [Fact] + public void GetItem_CachedTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var cache = new TimelineListViewCache(listView, tab, new()); + + var post = this.CreatePost(); + tab.AddPostQueue(post); + tab.AddSubmit(); + + cache.CreateCache(startIndex: 0, endIndex: 0); + + post.IsRead = false; + + // IsRead の状態はキャッシュに未反映なので既読状態で返るのが正しい + var item = cache.GetItem(0); + Assert.Equal("", item.SubItems[5].Text); + } + [Fact] public void GetStyle_Font_ReadedTest() { @@ -507,5 +527,25 @@ public void GetStyle_BackColor_NormalTest() var style = cache.GetStyle(tab.IndexOf(targetPost.StatusId)); Assert.Equal(ListItemBackColor.None, style.BackColor); } + + [Fact] + public void GetStyle_CachedTest() + { + var tab = new PublicSearchTabModel("tab"); + using var listView = new DetailsListView(); + using var cache = new TimelineListViewCache(listView, tab, new()); + + var post = this.CreatePost(); + tab.AddPostQueue(post); + tab.AddSubmit(); + + cache.CreateCache(startIndex: 0, endIndex: 0); + + post.IsFav = true; + + // IsFav の状態はキャッシュに未反映なので None が返るのが正しい + var style = cache.GetStyle(0); + Assert.Equal(ListItemForeColor.None, style.ForeColor); + } } } diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index c3fd7d453..6ba9d1c06 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -101,7 +101,7 @@ public void UpdateListSize() } } - private void CreateCache(int startIndex, int endIndex) + internal void CreateCache(int startIndex, int endIndex) { if (this.tab.AllCount == 0) return; From 20d6826be5c288090d680f149b5986e40051dc4d Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 22 May 2022 02:00:27 +0900 Subject: [PATCH 197/402] =?UTF-8?q?ListView=E3=81=AE=E3=82=B9=E3=82=AF?= =?UTF-8?q?=E3=83=AD=E3=83=BC=E3=83=AB=E4=BD=8D=E7=BD=AE=E3=83=BB=E9=81=B8?= =?UTF-8?q?=E6=8A=9E=E7=8A=B6=E6=85=8B=E3=82=92=E4=BF=9D=E6=8C=81=E3=81=99?= =?UTF-8?q?=E3=82=8BTimelineListViewState=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/TabModelTest.cs | 2 - OpenTween/Models/TabModel.cs | 3 - OpenTween/OpenTween.csproj | 1 + OpenTween/TimelineListViewState.cs | 269 ++++++++++++++++++++++++ OpenTween/Tween.cs | 271 ++----------------------- 5 files changed, 291 insertions(+), 255 deletions(-) create mode 100644 OpenTween/TimelineListViewState.cs diff --git a/OpenTween.Tests/Models/TabModelTest.cs b/OpenTween.Tests/Models/TabModelTest.cs index 518334216..2cf139d1a 100644 --- a/OpenTween.Tests/Models/TabModelTest.cs +++ b/OpenTween.Tests/Models/TabModelTest.cs @@ -117,7 +117,6 @@ public void SelectPosts_Test() Assert.Equal(new[] { posts[0], posts[2] }, tab.SelectedPosts); Assert.Equal(posts[0], tab.SelectedPost); Assert.Equal(0, tab.SelectedIndex); - Assert.Equal(new[] { 0, 2 }, tab.SelectedIndices); } [Fact] @@ -134,7 +133,6 @@ public void SelectPosts_EmptyTest() Assert.Empty(tab.SelectedPosts); Assert.Null(tab.SelectedPost); Assert.Equal(-1, tab.SelectedIndex); - Assert.Empty(tab.SelectedIndices); } [Fact] diff --git a/OpenTween/Models/TabModel.cs b/OpenTween/Models/TabModel.cs index cd6575eb5..d9c054279 100644 --- a/OpenTween/Models/TabModel.cs +++ b/OpenTween/Models/TabModel.cs @@ -100,9 +100,6 @@ public int SelectedIndex } } - public int[] SelectedIndices - => this.SelectedPosts.Select(x => this.IndexOf(x.StatusId)).Where(x => x != -1).ToArray(); - public long? AnchorStatusId { get; set; } public PostClass? AnchorPost diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 33bb4ea46..bdfa7ba0f 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -204,6 +204,7 @@ + UserControl diff --git a/OpenTween/TimelineListViewState.cs b/OpenTween/TimelineListViewState.cs new file mode 100644 index 000000000..9b64d926e --- /dev/null +++ b/OpenTween/TimelineListViewState.cs @@ -0,0 +1,269 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2007-2011 kiri_feather (@kiri_feather) +// (c) 2008-2011 Moz (@syo68k) +// (c) 2008-2011 takeshik (@takeshik) +// (c) 2010-2011 anis774 (@anis774) +// (c) 2010-2011 fantasticswallow (@f_swallow) +// (c) 2011 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General public License +// for more details. +// +// You should have received a copy of the GNU General public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; +using OpenTween.Models; +using OpenTween.OpenTweenCustomControl; + +namespace OpenTween +{ + public class TimelineListViewState + { + private readonly DetailsListView listView; + private readonly TabModel tab; + + private ListViewScroll savedScrollState; + private ListViewSelection savedSelectionState; + + internal readonly record struct ListViewScroll( + ScrollLockMode ScrollLockMode, + long? TopItemStatusId + ); + + internal enum ScrollLockMode + { + /// 固定しない + None, + + /// 最上部に固定する + FixedToTop, + + /// 最下部に固定する + FixedToBottom, + + /// の位置に固定する + FixedToItem, + } + + internal readonly record struct ListViewSelection( + long[] SelectedStatusIds, + long? SelectionMarkStatusId, + long? FocusedStatusId + ); + + public TimelineListViewState(DetailsListView listView, TabModel tab) + { + this.listView = listView; + this.tab = tab; + } + + public void Save(bool lockScroll) + { + this.savedScrollState = this.SaveListViewScroll(lockScroll); + this.savedSelectionState = this.SaveListViewSelection(); + } + + public void Restore() + { + this.RestoreScroll(); + this.RestoreSelection(); + } + + public void RestoreScroll() + => this.RestoreListViewScroll(this.savedScrollState); + + public void RestoreSelection() + => this.RestoreListViewSelection(this.savedSelectionState); + + /// + /// のスクロール位置に関する情報を として返します + /// + private ListViewScroll SaveListViewScroll(bool lockScroll) + { + var lockMode = this.GetScrollLockMode(lockScroll); + long? topItemStatusId = null; + + if (lockMode == ScrollLockMode.FixedToItem) + { + var topItemIndex = this.listView.TopItem?.Index ?? -1; + if (topItemIndex != -1 && topItemIndex < this.tab.AllCount) + topItemStatusId = this.tab.GetStatusIdAt(topItemIndex); + } + + return new ListViewScroll + { + ScrollLockMode = lockMode, + TopItemStatusId = topItemStatusId, + }; + } + + private ScrollLockMode GetScrollLockMode(bool lockScroll) + { + if (this.tab.SortMode == ComparerMode.Id) + { + if (this.tab.SortOrder == SortOrder.Ascending) + { + // Id昇順 + if (lockScroll) + return ScrollLockMode.None; + + // 最下行が表示されていたら、最下行へ強制スクロール。最下行が表示されていなかったら制御しない + + // 一番下に表示されているアイテム + var bottomItem = this.listView.GetItemAt(0, this.listView.ClientSize.Height - 1); + if (bottomItem == null || bottomItem.Index == this.listView.VirtualListSize - 1) + return ScrollLockMode.FixedToBottom; + else + return ScrollLockMode.None; + } + else + { + // Id降順 + if (lockScroll) + return ScrollLockMode.FixedToItem; + + // 最上行が表示されていたら、制御しない。最上行が表示されていなかったら、現在表示位置へ強制スクロール + var topItem = this.listView.TopItem; + if (topItem == null || topItem.Index == 0) + return ScrollLockMode.FixedToTop; + else + return ScrollLockMode.FixedToItem; + } + } + else + { + return ScrollLockMode.FixedToItem; + } + } + + /// + /// の選択状態を として返します + /// + private ListViewSelection SaveListViewSelection() + { + if (this.listView.VirtualListSize == 0) + { + return new ListViewSelection + { + SelectedStatusIds = Array.Empty(), + SelectionMarkStatusId = null, + FocusedStatusId = null, + }; + } + + return new ListViewSelection + { + SelectedStatusIds = this.tab.SelectedStatusIds, + FocusedStatusId = this.GetFocusedStatusId(), + SelectionMarkStatusId = this.GetSelectionMarkStatusId(), + }; + } + + private long? GetFocusedStatusId() + { + var index = this.listView.FocusedItem?.Index ?? -1; + + return index != -1 && index < this.tab.AllCount ? this.tab.GetStatusIdAt(index) : (long?)null; + } + + private long? GetSelectionMarkStatusId() + { + var index = this.listView.SelectionMark; + + return index != -1 && index < this.tab.AllCount ? this.tab.GetStatusIdAt(index) : (long?)null; + } + + /// + /// によって保存されたスクロール位置を復元します + /// + private void RestoreListViewScroll(ListViewScroll listScroll) + { + if (this.listView.VirtualListSize == 0) + return; + + switch (listScroll.ScrollLockMode) + { + case ScrollLockMode.FixedToTop: + this.listView.EnsureVisible(0); + break; + case ScrollLockMode.FixedToBottom: + this.listView.EnsureVisible(this.listView.VirtualListSize - 1); + break; + case ScrollLockMode.FixedToItem: + var topIndex = listScroll.TopItemStatusId != null ? this.tab.IndexOf(listScroll.TopItemStatusId.Value) : -1; + if (topIndex != -1) + { + var topItem = this.listView.Items[topIndex]; + try + { + this.listView.TopItem = topItem; + } + catch (NullReferenceException) + { + this.listView.EnsureVisible(this.listView.VirtualListSize - 1); + this.listView.EnsureVisible(topIndex); + } + } + break; + case ScrollLockMode.None: + default: + break; + } + } + + /// + /// によって保存された選択状態を復元します + /// + private void RestoreListViewSelection(ListViewSelection listSelection) + { + var invalidateBounds = (Rectangle?)null; + + var previousFocusedItem = this.listView.FocusedItem; + if (previousFocusedItem != null) + invalidateBounds = previousFocusedItem.Bounds; + + // status_id から ListView 上のインデックスに変換 + if (listSelection.SelectedStatusIds != null) + { + var selectedIndices = this.tab.IndexOf(listSelection.SelectedStatusIds).Where(x => x != -1).ToArray(); + this.listView.SelectItems(selectedIndices); + } + + if (listSelection.FocusedStatusId != null) + { + var focusedIndex = this.tab.IndexOf(listSelection.FocusedStatusId.Value); + if (focusedIndex != -1) + this.listView.Items[focusedIndex].Focused = true; + } + + if (listSelection.SelectionMarkStatusId != null) + { + var selectionMarkIndex = this.tab.IndexOf(listSelection.SelectionMarkStatusId.Value); + if (selectionMarkIndex != -1) + this.listView.SelectionMark = selectionMarkIndex; + } + + if (invalidateBounds != null) + this.listView.Invalidate(invalidateBounds.Value); + } + } +} diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index a89c69581..194dc47fc 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -182,6 +182,7 @@ public partial class TweenMain : OTBaseForm private TimelineListViewCache? listCache; private TimelineListViewDrawer? listDrawer; + private readonly Dictionary listViewState = new(); private bool isColumnChanged = false; @@ -882,14 +883,11 @@ internal void MarkSettingAtIdModified() private void RefreshTimeline() { - var curTabModel = this.CurrentTab; var curListView = this.CurrentListView; // 現在表示中のタブのスクロール位置を退避 - var curListScroll = this.SaveListViewScroll(curListView, curTabModel); - - // 各タブのリスト上の選択位置などを退避 - var listSelections = this.SaveListViewSelection(); + var currentListViewState = this.listViewState[this.CurrentTabName]; + currentListViewState.Save(this.ListLockMenuItem.Checked); // 更新確定 int addCount; @@ -910,7 +908,7 @@ private void RefreshTimeline() this.listCache.UpdateListSize(); // 選択位置などを復元 - this.RestoreListViewSelection(curListView, curTabModel, listSelections[curTabModel.TabName]); + currentListViewState.RestoreSelection(); } } @@ -932,7 +930,7 @@ private void RefreshTimeline() } // スクロール位置を復元 - this.RestoreListViewScroll(curListView, curTabModel, curListScroll); + currentListViewState.RestoreScroll(); // 新着通知 this.NotifyNewPosts(notifyPosts, soundFile, addCount, newMentionOrDm); @@ -943,205 +941,6 @@ private void RefreshTimeline() this.HashSupl.AddRangeItem(this.tw.GetHashList()); } - internal readonly record struct ListViewScroll( - ScrollLockMode ScrollLockMode, - long? TopItemStatusId - ); - - internal enum ScrollLockMode - { - /// 固定しない - None, - - /// 最上部に固定する - FixedToTop, - - /// 最下部に固定する - FixedToBottom, - - /// の位置に固定する - FixedToItem, - } - - /// - /// のスクロール位置に関する情報を として返します - /// - private ListViewScroll SaveListViewScroll(DetailsListView listView, TabModel tab) - { - var lockMode = this.GetScrollLockMode(listView); - long? topItemStatusId = null; - - if (lockMode == ScrollLockMode.FixedToItem) - { - var topItemIndex = listView.TopItem?.Index ?? -1; - if (topItemIndex != -1 && topItemIndex < tab.AllCount) - topItemStatusId = tab.GetStatusIdAt(topItemIndex); - } - - return new ListViewScroll - { - ScrollLockMode = lockMode, - TopItemStatusId = topItemStatusId, - }; - } - - private ScrollLockMode GetScrollLockMode(DetailsListView listView) - { - if (this.statuses.SortMode == ComparerMode.Id) - { - if (this.statuses.SortOrder == SortOrder.Ascending) - { - // Id昇順 - if (this.ListLockMenuItem.Checked) - return ScrollLockMode.None; - - // 最下行が表示されていたら、最下行へ強制スクロール。最下行が表示されていなかったら制御しない - - // 一番下に表示されているアイテム - var bottomItem = listView.GetItemAt(0, listView.ClientSize.Height - 1); - if (bottomItem == null || bottomItem.Index == listView.VirtualListSize - 1) - return ScrollLockMode.FixedToBottom; - else - return ScrollLockMode.None; - } - else - { - // Id降順 - if (this.ListLockMenuItem.Checked) - return ScrollLockMode.FixedToItem; - - // 最上行が表示されていたら、制御しない。最上行が表示されていなかったら、現在表示位置へ強制スクロール - var topItem = listView.TopItem; - if (topItem == null || topItem.Index == 0) - return ScrollLockMode.FixedToTop; - else - return ScrollLockMode.FixedToItem; - } - } - else - { - return ScrollLockMode.FixedToItem; - } - } - - internal readonly record struct ListViewSelection( - long[]? SelectedStatusIds, - long? SelectionMarkStatusId, - long? FocusedStatusId - ); - - /// - /// の選択状態を として返します - /// - private IReadOnlyDictionary SaveListViewSelection() - { - var listsDict = new Dictionary(); - - foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) - { - var listView = (DetailsListView)this.ListTab.TabPages[index].Tag; - listsDict[tab.TabName] = this.SaveListViewSelection(listView, tab); - } - - return listsDict; - } - - /// - /// の選択状態を として返します - /// - private ListViewSelection SaveListViewSelection(DetailsListView listView, TabModel tab) - { - if (listView.VirtualListSize == 0) - { - return new ListViewSelection - { - SelectedStatusIds = Array.Empty(), - SelectionMarkStatusId = null, - FocusedStatusId = null, - }; - } - - return new ListViewSelection - { - SelectedStatusIds = tab.SelectedStatusIds, - FocusedStatusId = this.GetFocusedStatusId(listView, tab), - SelectionMarkStatusId = this.GetSelectionMarkStatusId(listView, tab), - }; - } - - private long? GetFocusedStatusId(DetailsListView listView, TabModel tab) - { - var index = listView.FocusedItem?.Index ?? -1; - - return index != -1 && index < tab.AllCount ? tab.GetStatusIdAt(index) : (long?)null; - } - - private long? GetSelectionMarkStatusId(DetailsListView listView, TabModel tab) - { - var index = listView.SelectionMark; - - return index != -1 && index < tab.AllCount ? tab.GetStatusIdAt(index) : (long?)null; - } - - /// - /// によって保存されたスクロール位置を復元します - /// - private void RestoreListViewScroll(DetailsListView listView, TabModel tab, ListViewScroll listScroll) - { - if (listView.VirtualListSize == 0) - return; - - switch (listScroll.ScrollLockMode) - { - case ScrollLockMode.FixedToTop: - listView.EnsureVisible(0); - break; - case ScrollLockMode.FixedToBottom: - listView.EnsureVisible(listView.VirtualListSize - 1); - break; - case ScrollLockMode.FixedToItem: - var topIndex = listScroll.TopItemStatusId != null ? tab.IndexOf(listScroll.TopItemStatusId.Value) : -1; - if (topIndex != -1) - { - var topItem = listView.Items[topIndex]; - try - { - listView.TopItem = topItem; - } - catch (NullReferenceException) - { - listView.EnsureVisible(listView.VirtualListSize - 1); - listView.EnsureVisible(topIndex); - } - } - break; - case ScrollLockMode.None: - default: - break; - } - } - - /// - /// によって保存された選択状態を復元します - /// - private void RestoreListViewSelection(DetailsListView listView, TabModel tab, ListViewSelection listSelection) - { - // status_id から ListView 上のインデックスに変換 - int[]? selectedIndices = null; - if (listSelection.SelectedStatusIds != null) - selectedIndices = tab.IndexOf(listSelection.SelectedStatusIds).Where(x => x != -1).ToArray(); - - var focusedIndex = -1; - if (listSelection.FocusedStatusId != null) - focusedIndex = tab.IndexOf(listSelection.FocusedStatusId.Value); - - var selectionMarkIndex = -1; - if (listSelection.SelectionMarkStatusId != null) - selectionMarkIndex = tab.IndexOf(listSelection.SelectionMarkStatusId.Value); - - this.SelectListItem(listView, selectedIndices, focusedIndex, selectionMarkIndex); - } - private bool BalloonRequired() { if (this.initial) @@ -2983,20 +2782,13 @@ private void SetTabAlignment() var newAlignment = this.settings.Common.ViewTabBottom ? TabAlignment.Bottom : TabAlignment.Top; if (this.ListTab.Alignment == newAlignment) return; - // 各タブのリスト上の選択位置などを退避 - var listSelections = this.SaveListViewSelection(); + // リスト上の選択位置などを退避 + var currentListViewState = this.listViewState[this.CurrentTabName]; + currentListViewState.Save(this.ListLockMenuItem.Checked); this.ListTab.Alignment = newAlignment; - foreach (var (tab, index) in this.statuses.Tabs.WithIndex()) - { - var lst = (DetailsListView)this.ListTab.TabPages[index].Tag; - using (ControlTransaction.Update(lst)) - { - // 選択位置などを復元 - this.RestoreListViewSelection(lst, tab, listSelections[tab.TabName]); - } - } + currentListViewState.Restore(); } private void ApplyListViewIconSize(MyCommon.IconSizes iconSz) @@ -3318,6 +3110,9 @@ public bool AddNewTab(TabModel tab, bool startup) listCustom.HScrolled += this.MyList_HScrolled; } + var state = new TimelineListViewState(listCustom, tab); + this.listViewState[tab.TabName] = state; + return true; } @@ -3350,6 +3145,8 @@ public bool RemoveSpecifiedTab(string tabName, bool confirm) this.SetListProperty(); // 他のタブに列幅等を反映 + this.listViewState.Remove(tabName); + // オブジェクトインスタンスの削除 var listCustom = (DetailsListView)tabPage.Tag; tabPage.Tag = null; @@ -8073,6 +7870,10 @@ private void ListTabSelect(TabPage tabPage) { this.SetListProperty(); + var previousTabName = this.CurrentTabName; + if (this.listViewState.TryGetValue(previousTabName, out var previousListViewState)) + previousListViewState.Save(this.ListLockMenuItem.Checked); + this.listCache?.PurgeCache(); this.statuses.SelectTab(tabPage.Text); @@ -8083,7 +7884,9 @@ private void ListTabSelect(TabPage tabPage) tab.ClearAnchor(); var listView = this.CurrentListView; - listView.SelectItems(tab.SelectedIndices); + + var currentListViewState = this.listViewState[tab.TabName]; + currentListViewState.Restore(); if (this.Use2ColumnsMode) { @@ -8142,38 +7945,6 @@ private void SelectListItem(DetailsListView lView, int index) if (flg) lView.Invalidate(bnd); } - private void SelectListItem(DetailsListView lView, int[]? index, int focusedIndex, int selectionMarkIndex) - { - // 複数 - var bnd = new Rectangle(); - var flg = false; - var item = lView.FocusedItem; - if (item != null) - { - bnd = item.Bounds; - flg = true; - } - - if (index != null) - { - lView.SelectItems(index); - } - if (selectionMarkIndex > -1 && lView.VirtualListSize > selectionMarkIndex) - { - lView.SelectionMark = selectionMarkIndex; - } - if (focusedIndex > -1 && lView.VirtualListSize > focusedIndex) - { - lView.Items[focusedIndex].Focused = true; - } - else if (index != null && index.Length != 0) - { - lView.Items[index.Last()].Focused = true; - } - - if (flg) lView.Invalidate(bnd); - } - private async void TweenMain_Shown(object sender, EventArgs e) { this.NotifyIcon1.Visible = true; From a730ac5193afc724c50a28c6200109867388863d Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 22 May 2022 19:49:25 +0900 Subject: [PATCH 198/402] =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=89=E3=82=AB?= =?UTF-8?q?=E3=83=90=E3=83=AC=E3=83=83=E3=82=B8=E3=81=AE=E5=8F=96=E5=BE=97?= =?UTF-8?q?=E3=81=ABAltCover=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- OpenTween.Tests/OpenTween.Tests.csproj | 1 + appveyor.yml | 19 +++++++++++++------ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 3222133e3..8b53f4f24 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /*/bin /*/obj /.vs +/__Instrumented +/coverage.xml Thumbs.db -TestResult.xml *.VisualState.xml diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index 1bfb67c83..a61fda3a5 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -25,6 +25,7 @@ + all diff --git a/appveyor.yml b/appveyor.yml index 8b24a7d7d..43838a454 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -50,22 +50,29 @@ build: verbosity: minimal cache: - - ./packages/ + - '%UserProfile%\.nuget\packages -> OpenTween\OpenTween.csproj, OpenTween.Tests\OpenTween.Tests.csproj' init: - git config --global core.autocrlf true before_build: - nuget restore - - choco install opencover.portable test_script: - - OpenCover.Console.exe -register -target:"%xunit20%\xunit.console.exe" -targetargs:".\OpenTween.Tests\bin\%CONFIGURATION%\net472\OpenTween.Tests.dll -noshadow -appveyor" -filter:"+[OpenTween*]* -[OpenTween.Tests]*" -excludebyfile:"*.Designer.cs" -skipautoprops -hideskipped:All -returntargetcode -output:coverage.xml + - cmd: | + set altCoverVersion=8.2.837 + set xunitVersion=2.4.1 + set targetFramework=net472 + set nugetPackages=%UserProfile%\.nuget\packages -after_test: - - npm install codecov --save - - ./node_modules/.bin/codecov -f coverage.xml + %nugetPackages%\altcover\%altCoverVersion%\tools\%targetFramework%\AltCover.exe --inputDirectory .\OpenTween.Tests\bin\Debug\%targetFramework%\ --outputDirectory .\__Instrumented\ --assemblyFilter "?^OpenTween(?!\.Tests)" --typeFilter "?^OpenTween\." --fileFilter "\.Designer\.cs" --visibleBranches + + %nugetPackages%\altcover\%altCoverVersion%\tools\%targetFramework%\AltCover.exe runner --recorderDirectory .\__Instrumented\ --executable %nugetPackages%\xunit.runner.console\%xunitVersion%\tools\%targetFramework%\xunit.console.exe -- .\__Instrumented\OpenTween.Tests.dll +after_test: + - ps: | + Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe -Outfile codecov.exe + .\codecov.exe -f coverage.xml - ps: | $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\Roslyn\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\' $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\' From 898e8152f77fb7633b402204c19139afed1c5b14 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 11 Jun 2022 01:41:59 +0900 Subject: [PATCH 199/402] =?UTF-8?q?Web=E3=83=96=E3=83=A9=E3=82=A6=E3=82=B6?= =?UTF-8?q?=E8=B5=B7=E5=8B=95=E6=99=82=E3=81=AE=E3=82=A8=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E3=83=A1=E3=83=83=E3=82=BB=E3=83=BC=E3=82=B8=E3=81=AE=E8=A1=A8?= =?UTF-8?q?=E7=A4=BA=E3=81=8CUI=E3=82=B9=E3=83=AC=E3=83=83=E3=83=89?= =?UTF-8?q?=E4=B8=8A=E3=81=A7=E8=A1=8C=E3=82=8F=E3=82=8C=E3=81=A6=E3=81=84?= =?UTF-8?q?=E3=81=AA=E3=81=84=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 96419a26 ("OpenUriInBrowserAsyncメソッドをMyCommonに移動") --- OpenTween/MyCommon.cs | 20 ++++++++++---------- OpenTween/Properties/Resources.Designer.cs | 2 +- OpenTween/Properties/Resources.en.resx | 2 +- OpenTween/Properties/Resources.resx | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/OpenTween/MyCommon.cs b/OpenTween/MyCommon.cs index d26e6a3f8..ba9d2d90a 100644 --- a/OpenTween/MyCommon.cs +++ b/OpenTween/MyCommon.cs @@ -987,21 +987,21 @@ public static bool IsNullOrEmpty([NotNullWhen(false)] string? value) public static Task OpenInBrowserAsync(IWin32Window? owner, string url) => MyCommon.OpenInBrowserAsync(owner, SettingManager.Instance.Local.BrowserPath, url); - public static Task OpenInBrowserAsync(IWin32Window? owner, string? browserPath, string url) + public static async Task OpenInBrowserAsync(IWin32Window? owner, string? browserPath, string url) { - return Task.Run(() => + try { - try + await Task.Run(() => { var startInfo = MyCommon.CreateBrowserProcessStartInfo(browserPath, url); Process.Start(startInfo); - } - catch (Win32Exception ex) - { - var message = string.Format(Properties.Resources.BrowserStartFailed, ex.ErrorCode); - MessageBox.Show(owner, message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - }); + }); + } + catch (Win32Exception ex) + { + var message = string.Format(Properties.Resources.BrowserStartFailed, ex.Message); + MessageBox.Show(owner, message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Warning); + } } public static ProcessStartInfo CreateBrowserProcessStartInfo(string? browserPathWithArgs, string url) diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 4884f6e9a..495820507 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -263,7 +263,7 @@ internal static string BitlyAuthorize_ErrorText { } /// - /// ブラウザの起動に失敗しました。エラーコード: {0} に類似しているローカライズされた文字列を検索します。 + /// ブラウザの起動に失敗しました: {0} に類似しているローカライズされた文字列を検索します。 /// internal static string BrowserStartFailed { get { diff --git a/OpenTween/Properties/Resources.en.resx b/OpenTween/Properties/Resources.en.resx index 1962bb230..850c2d0de 100644 --- a/OpenTween/Properties/Resources.en.resx +++ b/OpenTween/Properties/Resources.en.resx @@ -22,7 +22,7 @@ Not authenticated Failed to connect auth server. Failed to authorize. ({0}) - Failed to start browser. Error code: {0} + Failed to start browser: {0} Executable (*.exe)|*.exe|All files (*.*)|*.* Choose the web browser : Block this user? diff --git a/OpenTween/Properties/Resources.resx b/OpenTween/Properties/Resources.resx index bd8363720..cbea09bfa 100644 --- a/OpenTween/Properties/Resources.resx +++ b/OpenTween/Properties/Resources.resx @@ -27,7 +27,7 @@ 未認証 認証サーバーに接続できませんでした。 認証に失敗しました ({0}) - ブラウザの起動に失敗しました。エラーコード: {0} + ブラウザの起動に失敗しました: {0} 実行形式ファイル(*.exe)|*.exe|すべてのファイル(*.*)|*.* ブラウザを指定してください をブロックします。よろしいですか? From 82bb6d929426f02a8b2dc162de1b68e873dc8526 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 11 Jun 2022 10:43:54 +0900 Subject: [PATCH 200/402] =?UTF-8?q?ChangeLog=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 898e8152f77fb7633b402204c19139afed1c5b14 での変更を反映 --- OpenTween/Resources/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index d4c8f70ab..e63e69c92 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -20,6 +20,7 @@ * FIX: 起動直後の時点で発言詳細欄の背景色設定が適用されていない不具合を修正 * FIX: 自分のツイートに対する「@返信ALL」で自分宛のMentionが付かない不具合を修正 (thx @doug_lee42!) * FIX: 関連発言表示によって内部の未読状態と未読表示が一致しない状態になる不具合を修正 (thx @wal_san!) + * FIX: Webブラウザ起動時にエラーが発生した場合に正しくエラーメッセージが表示されない不具合を修正 ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました From 0bc9c513dc266a091c88a13f712dad433755e483 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 12 Jun 2022 10:25:21 +0900 Subject: [PATCH 201/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E9=81=B8=E6=8A=9E=E7=8A=B6=E6=85=8B=E3=81=AE=E5=A4=89?= =?UTF-8?q?=E5=8C=96=E3=81=8C=E5=83=85=E3=81=8B=E3=81=AB=E9=81=85=E3=82=8C?= =?UTF-8?q?=E3=81=A6=E6=8F=8F=E7=94=BB=E3=81=95=E3=82=8C=E3=82=8B=E4=B8=8D?= =?UTF-8?q?=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 543c9606 ("発言一覧のスタイル情報もキャッシュ対象とし、スタイルに変化が生じた行のみ再描画を行う") --- OpenTween/TimelineListViewCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenTween/TimelineListViewCache.cs b/OpenTween/TimelineListViewCache.cs index 6ba9d1c06..c35b95284 100644 --- a/OpenTween/TimelineListViewCache.cs +++ b/OpenTween/TimelineListViewCache.cs @@ -236,7 +236,7 @@ public void RefreshStyle() this.ApplyListItemStyle(item, style); } - updatedIndices.Remove(this.tab.SelectedIndex); + updatedIndices.Add(this.tab.SelectedIndex); this.listView.RefreshItems(updatedIndices); } From 134b6f89eb5a4aba80327777d479183eac10aecf Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 8 Jul 2022 02:21:36 +0900 Subject: [PATCH 202/402] =?UTF-8?q?=E3=83=95=E3=82=A9=E3=83=B3=E3=83=88?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E5=BE=8C=E3=81=AB=E3=82=BF=E3=83=96=E3=82=92?= =?UTF-8?q?=E5=88=87=E3=82=8A=E6=9B=BF=E3=81=88=E3=82=8B=E3=81=A8=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=81=8C=E7=99=BA=E7=94=9F=E3=81=99=E3=82=8B?= =?UTF-8?q?=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: 6555e55f ("Font, Color, Brushインスタンスの管理をThemeManagerクラスに分離") --- OpenTween/Tween.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 194dc47fc..453b9b547 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -2715,8 +2715,6 @@ private async void SettingStripMenuItem_Click(object sender, EventArgs e) using (ControlTransaction.Update(lst)) { lst.GridLines = this.settings.Common.ShowGrid; - lst.Font = this.themeManager.FontReaded; - lst.BackColor = this.themeManager.ColorListBackcolor; if (this.Use2ColumnsMode != oldIconCol) this.ResetColumns(lst); @@ -3089,8 +3087,6 @@ public bool AddNewTab(TabModel tab, bool startup) listCustom.View = View.Details; listCustom.OwnerDraw = true; listCustom.VirtualMode = true; - listCustom.Font = this.themeManager.FontReaded; - listCustom.BackColor = this.themeManager.ColorListBackcolor; listCustom.GridLines = this.settings.Common.ShowGrid; listCustom.AllowDrop = true; From e03de8b09129ced44db9f2269fd557f9f5cb7261 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 29 May 2022 01:10:58 +0900 Subject: [PATCH 203/402] =?UTF-8?q?Recent=E3=82=BF=E3=83=96=E3=81=AE?= =?UTF-8?q?=E3=83=84=E3=82=A4=E3=83=BC=E3=83=88=E5=8F=96=E5=BE=97=E3=81=AB?= =?UTF-8?q?Twitter=20API=20v2=E3=82=92=E4=BD=BF=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Api/TwitterApiTest.cs | 28 +++++++ .../Api/TwitterV2/GetTimelineRequestTest.cs | 65 +++++++++++++++ OpenTween/Api/DataModel/TwitterV2TweetId.cs | 34 ++++++++ OpenTween/Api/DataModel/TwitterV2TweetIds.cs | 34 ++++++++ OpenTween/Api/TwitterApi.cs | 14 ++++ OpenTween/Api/TwitterV2/GetTimelineRequest.cs | 79 +++++++++++++++++++ OpenTween/ApiInfoDialog.cs | 3 +- OpenTween/OpenTween.csproj | 3 + OpenTween/Resources/ChangeLog.txt | 2 + OpenTween/Tween.cs | 35 +++++--- OpenTween/Twitter.cs | 23 +++--- 11 files changed, 296 insertions(+), 24 deletions(-) create mode 100644 OpenTween.Tests/Api/TwitterV2/GetTimelineRequestTest.cs create mode 100644 OpenTween/Api/DataModel/TwitterV2TweetId.cs create mode 100644 OpenTween/Api/DataModel/TwitterV2TweetIds.cs create mode 100644 OpenTween/Api/TwitterV2/GetTimelineRequest.cs diff --git a/OpenTween.Tests/Api/TwitterApiTest.cs b/OpenTween.Tests/Api/TwitterApiTest.cs index db9bd0ee7..85ea02e00 100644 --- a/OpenTween.Tests/Api/TwitterApiTest.cs +++ b/OpenTween.Tests/Api/TwitterApiTest.cs @@ -197,6 +197,34 @@ await twitterApi.StatusesShow(statusId: 100L) mock.VerifyAll(); } + [Fact] + public async Task StatusesLookup_Test() + { + var mock = new Mock(); + mock.Setup(x => + x.GetAsync( + new Uri("statuses/lookup.json", UriKind.Relative), + new Dictionary + { + { "id", "100,200" }, + { "include_entities", "true" }, + { "include_ext_alt_text", "true" }, + { "tweet_mode", "extended" }, + }, + "/statuses/lookup" + ) + ) + .ReturnsAsync(Array.Empty()); + + using var twitterApi = new TwitterApi(ApiKey.Create("fake_consumer_key"), ApiKey.Create("fake_consumer_secret")); + twitterApi.ApiConnection = mock.Object; + + await twitterApi.StatusesLookup(statusIds: new[] { "100", "200" }) + .ConfigureAwait(false); + + mock.VerifyAll(); + } + [Fact] public async Task StatusesUpdate_Test() { diff --git a/OpenTween.Tests/Api/TwitterV2/GetTimelineRequestTest.cs b/OpenTween.Tests/Api/TwitterV2/GetTimelineRequestTest.cs new file mode 100644 index 000000000..82ed7e59a --- /dev/null +++ b/OpenTween.Tests/Api/TwitterV2/GetTimelineRequestTest.cs @@ -0,0 +1,65 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2922 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Moq; +using OpenTween.Api.DataModel; +using OpenTween.Connection; +using Xunit; + +namespace OpenTween.Api.TwitterV2 +{ + public class GetTimelineRequestTest + { + [Fact] + public async Task StatusesMentionsTimeline_Test() + { + var mock = new Mock(); + mock.Setup(x => + x.GetAsync( + new Uri("/2/users/100/timelines/reverse_chronological", UriKind.Relative), + new Dictionary + { + { "tweet.fields", "id" }, + { "max_results", "200" }, + { "until_id", "900" }, + { "since_id", "100" }, + }, + "/2/users/:id/timelines/reverse_chronological" + ) + ) + .ReturnsAsync(new TwitterV2TweetIds()); + + var request = new GetTimelineRequest(userId: 100L) + { + MaxResults = 200, + SinceId = "100", + UntilId = "900", + }; + + await request.Send(mock.Object).ConfigureAwait(false); + + mock.VerifyAll(); + } + } +} diff --git a/OpenTween/Api/DataModel/TwitterV2TweetId.cs b/OpenTween/Api/DataModel/TwitterV2TweetId.cs new file mode 100644 index 000000000..cdec92859 --- /dev/null +++ b/OpenTween/Api/DataModel/TwitterV2TweetId.cs @@ -0,0 +1,34 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable annotations + +using System.Runtime.Serialization; + +namespace OpenTween.Api.DataModel +{ + [DataContract] + public class TwitterV2TweetId + { + [DataMember(Name = "id")] + public string Id { get; set; } + } +} diff --git a/OpenTween/Api/DataModel/TwitterV2TweetIds.cs b/OpenTween/Api/DataModel/TwitterV2TweetIds.cs new file mode 100644 index 000000000..6b61b9c4d --- /dev/null +++ b/OpenTween/Api/DataModel/TwitterV2TweetIds.cs @@ -0,0 +1,34 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable annotations + +using System.Runtime.Serialization; + +namespace OpenTween.Api.DataModel +{ + [DataContract] + public class TwitterV2TweetIds + { + [DataMember(Name = "data")] + public TwitterV2TweetId[] Data { get; set; } + } +} diff --git a/OpenTween/Api/TwitterApi.cs b/OpenTween/Api/TwitterApi.cs index 6e957c64a..1f5c7ce9f 100644 --- a/OpenTween/Api/TwitterApi.cs +++ b/OpenTween/Api/TwitterApi.cs @@ -138,6 +138,20 @@ public Task StatusesShow(long statusId) return this.Connection.GetAsync(endpoint, param, "/statuses/show/:id"); } + public Task StatusesLookup(IReadOnlyList statusIds) + { + var endpoint = new Uri("statuses/lookup.json", UriKind.Relative); + var param = new Dictionary + { + ["id"] = string.Join(",", statusIds), + ["include_entities"] = "true", + ["include_ext_alt_text"] = "true", + ["tweet_mode"] = "extended", + }; + + return this.Connection.GetAsync(endpoint, param, "/statuses/lookup"); + } + public Task> StatusesUpdate( string status, long? replyToId, diff --git a/OpenTween/Api/TwitterV2/GetTimelineRequest.cs b/OpenTween/Api/TwitterV2/GetTimelineRequest.cs new file mode 100644 index 000000000..fcc537d6b --- /dev/null +++ b/OpenTween/Api/TwitterV2/GetTimelineRequest.cs @@ -0,0 +1,79 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using OpenTween.Api.DataModel; +using OpenTween.Connection; + +namespace OpenTween.Api.TwitterV2 +{ + public class GetTimelineRequest + { + public static readonly string EndpointName = "/2/users/:id/timelines/reverse_chronological"; + + public long UserId { get; set; } + + public int? MaxResults { get; set; } + + public string? UntilId { get; set; } + + public string? SinceId { get; set; } + + public GetTimelineRequest(long userId) + => this.UserId = userId; + + private Uri CreateEndpointUri() + => new($"/2/users/{this.UserId}/timelines/reverse_chronological", UriKind.Relative); + + private Dictionary CreateParameters() + { + var param = new Dictionary + { + ["tweet.fields"] = "id", + }; + + if (this.MaxResults != null) + param["max_results"] = this.MaxResults.ToString(); + + if (this.UntilId != null) + param["until_id"] = this.UntilId; + + if (this.SinceId != null) + param["since_id"] = this.SinceId; + + return param; + } + + public Task Send(IApiConnection apiConnection) + { + var uri = this.CreateEndpointUri(); + var param = this.CreateParameters(); + + return apiConnection.GetAsync(uri, param, EndpointName); + } + } +} diff --git a/OpenTween/ApiInfoDialog.cs b/OpenTween/ApiInfoDialog.cs index e8240a097..37192c661 100644 --- a/OpenTween/ApiInfoDialog.cs +++ b/OpenTween/ApiInfoDialog.cs @@ -31,6 +31,7 @@ using System.Threading.Tasks; using System.Windows.Forms; using OpenTween.Api; +using OpenTween.Api.TwitterV2; namespace OpenTween { @@ -41,7 +42,7 @@ public ApiInfoDialog() private readonly List tlEndpoints = new() { - "/statuses/home_timeline", + GetTimelineRequest.EndpointName, "/statuses/mentions_timeline", "/statuses/show/:id", "/statuses/user_timeline", diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index bdfa7ba0f..907c3e7d7 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -92,6 +92,7 @@ + @@ -100,6 +101,8 @@ + + Code diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index e63e69c92..3d1d92696 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,8 @@ 更新履歴 ==== Ver 2.5.1-dev(2022/xx/xx) + * NEW: Recentタブの発言の取得に Twitter API v2 を使用 + - 従来の API v1.1 と比べて、15分間に取得できる回数の制限が15→180回に緩和されます * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) * NEW: 発言詳細欄の名前やアイコンのクリックによるプロフィール表示に対応 * NEW: クリップボード経由での複数枚の画像ファイル添付に対応 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 453b9b547..6292d5ff8 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -52,6 +52,7 @@ using System.Windows.Forms; using OpenTween.Api; using OpenTween.Api.DataModel; +using OpenTween.Api.TwitterV2; using OpenTween.Connection; using OpenTween.MediaUploadServices; using OpenTween.Models; @@ -7042,7 +7043,7 @@ private void SetApiStatusLabel(string? endpointName = null) // 表示中のタブに応じて更新 endpointName = tabType switch { - MyCommon.TabUsageType.Home => "/statuses/home_timeline", + MyCommon.TabUsageType.Home => GetTimelineRequest.EndpointName, MyCommon.TabUsageType.UserDefined => "/statuses/home_timeline", MyCommon.TabUsageType.Mentions => "/statuses/mentions_timeline", MyCommon.TabUsageType.Favorites => "/favorites/list", @@ -7058,18 +7059,26 @@ private void SetApiStatusLabel(string? endpointName = null) else { // 表示中のタブに関連する endpoint であれば更新 - var update = endpointName switch - { - "/statuses/home_timeline" => tabType == MyCommon.TabUsageType.Home || tabType == MyCommon.TabUsageType.UserDefined, - "/statuses/mentions_timeline" => tabType == MyCommon.TabUsageType.Mentions, - "/favorites/list" => tabType == MyCommon.TabUsageType.Favorites, - "/direct_messages/events/list" => tabType == MyCommon.TabUsageType.DirectMessage, - "/statuses/user_timeline" => tabType == MyCommon.TabUsageType.UserTimeline, - "/lists/statuses" => tabType == MyCommon.TabUsageType.Lists, - "/search/tweets" => tabType == MyCommon.TabUsageType.PublicSearch, - "/statuses/show/:id" => tabType == MyCommon.TabUsageType.Related, - _ => false, - }; + bool update; + if (endpointName == GetTimelineRequest.EndpointName) + { + update = tabType == MyCommon.TabUsageType.Home || tabType == MyCommon.TabUsageType.UserDefined; + } + else + { + update = endpointName switch + { + "/statuses/mentions_timeline" => tabType == MyCommon.TabUsageType.Mentions, + "/favorites/list" => tabType == MyCommon.TabUsageType.Favorites, + "/direct_messages/events/list" => tabType == MyCommon.TabUsageType.DirectMessage, + "/statuses/user_timeline" => tabType == MyCommon.TabUsageType.UserTimeline, + "/lists/statuses" => tabType == MyCommon.TabUsageType.Lists, + "/search/tweets" => tabType == MyCommon.TabUsageType.PublicSearch, + "/statuses/show/:id" => tabType == MyCommon.TabUsageType.Related, + _ => false, + }; + } + if (update) { this.toolStripApiGauge.ApiEndpoint = endpointName; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 0070f48eb..246894fab 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -44,6 +44,7 @@ using System.Windows.Forms; using OpenTween.Api; using OpenTween.Api.DataModel; +using OpenTween.Api.TwitterV2; using OpenTween.Connection; using OpenTween.Models; using OpenTween.Setting; @@ -547,17 +548,19 @@ public async Task GetHomeTimelineApi(bool read, HomeTabModel tab, bool more, boo var count = GetApiResultCount(MyCommon.WORKERTYPE.Timeline, more, startup); - TwitterStatus[] statuses; - if (more) + var request = new GetTimelineRequest(this.UserId) { - statuses = await this.Api.StatusesHomeTimeline(count, maxId: tab.OldestId) - .ConfigureAwait(false); - } - else - { - statuses = await this.Api.StatusesHomeTimeline(count) - .ConfigureAwait(false); - } + MaxResults = count, + UntilId = more ? tab.OldestId.ToString() : null, + }; + + var response = await request.Send(this.Api.Connection) + .ConfigureAwait(false); + + var tweetIds = response.Data.Select(x => x.Id).ToList(); + + var statuses = await this.Api.StatusesLookup(tweetIds) + .ConfigureAwait(false); var minimumId = this.CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.Timeline, tab, read); if (minimumId != null) From 26561242a3298d4eca668f7352a43d8b5ee6c702 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 29 May 2022 07:04:58 +0900 Subject: [PATCH 204/402] =?UTF-8?q?PostClass=E3=82=A4=E3=83=B3=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=83=B3=E3=82=B9=E3=81=AE=E7=94=9F=E6=88=90=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92TwitterPostFactory=E3=82=AF=E3=83=A9=E3=82=B9?= =?UTF-8?q?=E3=81=AB=E5=88=86=E9=9B=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/Models/PostClassTest.cs | 2 + .../Models/TwitterPostFactoryTest.cs | 643 ++++++++++++++++++ OpenTween.Tests/TwitterTest.cs | 318 --------- OpenTween/Models/PostClass.cs | 4 +- OpenTween/Models/TabInformations.cs | 2 +- OpenTween/Models/TwitterPostFactory.cs | 570 ++++++++++++++++ OpenTween/OpenTween.csproj | 1 + OpenTween/Twitter.cs | 517 +------------- 8 files changed, 1229 insertions(+), 828 deletions(-) create mode 100644 OpenTween.Tests/Models/TwitterPostFactoryTest.cs create mode 100644 OpenTween/Models/TwitterPostFactory.cs diff --git a/OpenTween.Tests/Models/PostClassTest.cs b/OpenTween.Tests/Models/PostClassTest.cs index e75575fb1..eebcf63e4 100644 --- a/OpenTween.Tests/Models/PostClassTest.cs +++ b/OpenTween.Tests/Models/PostClassTest.cs @@ -417,6 +417,8 @@ protected override async Task DeepExpandAsync() [Fact] public async Task ExpandedUrls_BasicScenario() { + PostClass.ExpandedUrlInfo.AutoExpand = true; + var post = new PostClass { Text = "bit.ly/abcde", diff --git a/OpenTween.Tests/Models/TwitterPostFactoryTest.cs b/OpenTween.Tests/Models/TwitterPostFactoryTest.cs new file mode 100644 index 000000000..a62d8a347 --- /dev/null +++ b/OpenTween.Tests/Models/TwitterPostFactoryTest.cs @@ -0,0 +1,643 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2013 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections.Generic; +using OpenTween.Api.DataModel; +using Xunit; + +namespace OpenTween.Models +{ + public class TwitterPostFactoryTest + { + private static readonly ISet EmptyIdSet = new HashSet(); + + private readonly Random random = new(); + + public TwitterPostFactoryTest() + => PostClass.ExpandedUrlInfo.AutoExpand = false; + + private TabInformations CreateTabinfo() + { + var tabinfo = new TabInformations(); + tabinfo.AddDefaultTabs(); + return tabinfo; + } + + private TwitterStatus CreateStatus() + { + var statusId = this.random.Next(10000); + + return new() + { + Id = statusId, + IdStr = statusId.ToString(), + CreatedAt = "Sat Jan 01 00:00:00 +0000 2022", + FullText = "hoge", + Source = "OpenTween", + Entities = new(), + User = this.CreateUser(), + }; + } + + private TwitterUser CreateUser() + { + var userId = this.random.Next(10000); + + return new() + { + Id = userId, + IdStr = userId.ToString(), + ScreenName = "tetete", + Name = "ててて", + ProfileImageUrlHttps = "https://example.com/profile.png", + }; + } + + [Fact] + public void CreateFromStatus_Test() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + var status = this.CreateStatus(); + var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds: EmptyIdSet); + + Assert.Equal(status.Id, post.StatusId); + Assert.Equal(new DateTimeUtc(2022, 1, 1, 0, 0, 0), post.CreatedAt); + Assert.Equal("hoge", post.Text); + Assert.Equal("hoge", post.TextFromApi); + Assert.Equal("hoge", post.TextSingleLine); + Assert.Equal("hoge", post.AccessibleText); + Assert.Empty(post.ReplyToList); + Assert.Empty(post.QuoteStatusIds); + Assert.Empty(post.ExpandedUrls); + Assert.Empty(post.Media); + Assert.Null(post.PostGeo); + Assert.Equal("OpenTween", post.Source); + Assert.Equal("https://www.opentween.org/", post.SourceUri?.OriginalString); + Assert.Equal(0, post.FavoritedCount); + Assert.False(post.IsFav); + Assert.False(post.IsDm); + Assert.False(post.IsDeleted); + Assert.False(post.IsRead); + Assert.False(post.IsExcludeReply); + Assert.False(post.FilterHit); + Assert.False(post.IsMark); + + Assert.False(post.IsReply); + Assert.Null(post.InReplyToStatusId); + Assert.Null(post.InReplyToUserId); + Assert.Null(post.InReplyToUser); + + Assert.Null(post.RetweetedId); + Assert.Null(post.RetweetedBy); + Assert.Null(post.RetweetedByUserId); + + Assert.Equal(status.User.Id, post.UserId); + Assert.Equal("tetete", post.ScreenName); + Assert.Equal("ててて", post.Nickname); + Assert.Equal("https://example.com/profile.png", post.ImageUrl); + Assert.False(post.IsProtect); + Assert.False(post.IsOwl); + Assert.False(post.IsMe); + } + + [Fact] + public void CreateFromStatus_AuthorTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + var status = this.CreateStatus(); + var selfUserId = status.User.Id; + var post = factory.CreateFromStatus(status, selfUserId, followerIds: EmptyIdSet); + + Assert.True(post.IsMe); + } + + [Fact] + public void CreateFromStatus_FollowerTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + var status = this.CreateStatus(); + var followerIds = new HashSet { status.User.Id }; + var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds); + + Assert.False(post.IsOwl); + } + + [Fact] + public void CreateFromStatus_NotFollowerTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + var status = this.CreateStatus(); + var followerIds = new HashSet { 30000L }; + var post = factory.CreateFromStatus(status, selfUserId: 20000L, followerIds); + + Assert.True(post.IsOwl); + } + + [Fact] + public void CreateFromStatus_RetweetTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + var originalStatus = this.CreateStatus(); + + var retweetStatus = this.CreateStatus(); + retweetStatus.RetweetedStatus = originalStatus; + retweetStatus.Source = "Twitter Web App"; + + var post = factory.CreateFromStatus(retweetStatus, selfUserId: 20000L, followerIds: EmptyIdSet); + + Assert.Equal(retweetStatus.Id, post.StatusId); + Assert.Equal(retweetStatus.User.Id, post.RetweetedByUserId); + Assert.Equal(originalStatus.Id, post.RetweetedId); + Assert.Equal(originalStatus.User.Id, post.UserId); + + Assert.Equal("OpenTween", post.Source); + Assert.Equal("https://www.opentween.org/", post.SourceUri?.OriginalString); + } + + private TwitterMessageEvent CreateDirectMessage(string senderId, string recipientId) + { + var messageId = this.random.Next(10000); + + return new() + { + Type = "message_create", + Id = messageId.ToString(), + CreatedTimestamp = "1640995200000", + MessageCreate = new() + { + SenderId = senderId, + Target = new() + { + RecipientId = recipientId, + }, + MessageData = new() + { + Text = "hoge", + Entities = new(), + }, + SourceAppId = "22519141", + }, + }; + } + + private Dictionary CreateApps() + { + return new() + { + ["22519141"] = new() + { + Id = "22519141", + Name = "OpenTween", + Url = "https://www.opentween.org/", + }, + }; + } + + [Fact] + public void CreateFromDirectMessageEvent_Test() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + + var selfUser = this.CreateUser(); + var otherUser = this.CreateUser(); + var eventItem = this.CreateDirectMessage(senderId: otherUser.IdStr, recipientId: selfUser.IdStr); + var users = new Dictionary() + { + [selfUser.IdStr] = selfUser, + [otherUser.IdStr] = otherUser, + }; + var apps = this.CreateApps(); + var post = factory.CreateFromDirectMessageEvent(eventItem, users, apps, selfUserId: selfUser.Id); + + Assert.Equal(long.Parse(eventItem.Id), post.StatusId); + Assert.Equal(new DateTimeUtc(2022, 1, 1, 0, 0, 0), post.CreatedAt); + Assert.Equal("hoge", post.Text); + Assert.Equal("hoge", post.TextFromApi); + Assert.Equal("hoge", post.TextSingleLine); + Assert.Equal("hoge", post.AccessibleText); + Assert.Empty(post.ReplyToList); + Assert.Empty(post.QuoteStatusIds); + Assert.Empty(post.ExpandedUrls); + Assert.Empty(post.Media); + Assert.Null(post.PostGeo); + Assert.Equal("OpenTween", post.Source); + Assert.Equal("https://www.opentween.org/", post.SourceUri?.OriginalString); + Assert.Equal(0, post.FavoritedCount); + Assert.False(post.IsFav); + Assert.True(post.IsDm); + Assert.False(post.IsDeleted); + Assert.False(post.IsRead); + Assert.False(post.IsExcludeReply); + Assert.False(post.FilterHit); + Assert.False(post.IsMark); + + Assert.False(post.IsReply); + Assert.Null(post.InReplyToStatusId); + Assert.Null(post.InReplyToUserId); + Assert.Null(post.InReplyToUser); + + Assert.Null(post.RetweetedId); + Assert.Null(post.RetweetedBy); + Assert.Null(post.RetweetedByUserId); + + Assert.Equal(otherUser.Id, post.UserId); + Assert.Equal("tetete", post.ScreenName); + Assert.Equal("ててて", post.Nickname); + Assert.Equal("https://example.com/profile.png", post.ImageUrl); + Assert.False(post.IsProtect); + Assert.True(post.IsOwl); + Assert.False(post.IsMe); + } + + [Fact] + public void CreateFromDirectMessageEvent_SenderTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + + var selfUser = this.CreateUser(); + var otherUser = this.CreateUser(); + var eventItem = this.CreateDirectMessage(senderId: selfUser.IdStr, recipientId: otherUser.IdStr); + var users = new Dictionary() + { + [selfUser.IdStr] = selfUser, + [otherUser.IdStr] = otherUser, + }; + var apps = this.CreateApps(); + var post = factory.CreateFromDirectMessageEvent(eventItem, users, apps, selfUserId: selfUser.Id); + + Assert.Equal(otherUser.Id, post.UserId); + Assert.False(post.IsOwl); + Assert.True(post.IsMe); + } + + [Fact] + public void CreateFromStatus_MediaAltTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + + var status = this.CreateStatus(); + status.FullText = "https://t.co/hoge"; + status.ExtendedEntities = new() + { + Media = new[] + { + new TwitterEntityMedia + { + Indices = new[] { 0, 17 }, + Url = "https://t.co/hoge", + DisplayUrl = "pic.twitter.com/hoge", + ExpandedUrl = "https://twitter.com/hoge/status/1234567890/photo/1", + AltText = "代替テキスト", + }, + }, + }; + + var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet); + + var accessibleText = string.Format(Properties.Resources.ImageAltText, "代替テキスト"); + Assert.Equal(accessibleText, post.AccessibleText); + Assert.Equal("pic.twitter.com/hoge", post.Text); + Assert.Equal("pic.twitter.com/hoge", post.TextFromApi); + Assert.Equal("pic.twitter.com/hoge", post.TextSingleLine); + } + + [Fact] + public void CreateFromStatus_MediaNoAltTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + + var status = this.CreateStatus(); + status.FullText = "https://t.co/hoge"; + status.ExtendedEntities = new() + { + Media = new[] + { + new TwitterEntityMedia + { + Indices = new[] { 0, 17 }, + Url = "https://t.co/hoge", + DisplayUrl = "pic.twitter.com/hoge", + ExpandedUrl = "https://twitter.com/hoge/status/1234567890/photo/1", + AltText = null, + }, + }, + }; + + var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet); + + Assert.Equal("pic.twitter.com/hoge", post.AccessibleText); + Assert.Equal("pic.twitter.com/hoge", post.Text); + Assert.Equal("pic.twitter.com/hoge", post.TextFromApi); + Assert.Equal("pic.twitter.com/hoge", post.TextSingleLine); + } + + [Fact] + public void CreateFromStatus_QuotedUrlTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + + var status = this.CreateStatus(); + status.FullText = "https://t.co/hoge"; + status.Entities = new() + { + Urls = new[] + { + new TwitterEntityUrl + { + Indices = new[] { 0, 17 }, + Url = "https://t.co/hoge", + DisplayUrl = "twitter.com/hoge/status/1…", + ExpandedUrl = "https://twitter.com/hoge/status/1234567890", + }, + }, + }; + status.QuotedStatus = new() + { + Id = 1234567890L, + IdStr = "1234567890", + User = new() + { + Id = 1111, + IdStr = "1111", + ScreenName = "foo", + }, + FullText = "test", + }; + + var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet); + + var accessibleText = string.Format(Properties.Resources.QuoteStatus_AccessibleText, "foo", "test"); + Assert.Equal(accessibleText, post.AccessibleText); + Assert.Equal("twitter.com/hoge/status/1…", post.Text); + Assert.Equal("twitter.com/hoge/status/1…", post.TextFromApi); + Assert.Equal("twitter.com/hoge/status/1…", post.TextSingleLine); + } + + [Fact] + public void CreateFromStatus_QuotedUrlWithPermelinkTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + + var status = this.CreateStatus(); + status.FullText = "hoge"; + status.QuotedStatus = new() + { + Id = 1234567890L, + IdStr = "1234567890", + User = new TwitterUser + { + Id = 1111, + IdStr = "1111", + ScreenName = "foo", + }, + FullText = "test", + }; + status.QuotedStatusPermalink = new() + { + Url = "https://t.co/hoge", + Display = "twitter.com/hoge/status/1…", + Expanded = "https://twitter.com/hoge/status/1234567890", + }; + + var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet); + + var accessibleText = "hoge " + string.Format(Properties.Resources.QuoteStatus_AccessibleText, "foo", "test"); + Assert.Equal(accessibleText, post.AccessibleText); + Assert.Equal("hoge twitter.com/hoge/status/1…", post.Text); + Assert.Equal("hoge twitter.com/hoge/status/1…", post.TextFromApi); + Assert.Equal("hoge twitter.com/hoge/status/1…", post.TextSingleLine); + } + + [Fact] + public void CreateFromStatus_QuotedUrlNoReferenceTest() + { + var factory = new TwitterPostFactory(this.CreateTabinfo()); + + var status = this.CreateStatus(); + status.FullText = "https://t.co/hoge"; + status.Entities = new() + { + Urls = new[] + { + new TwitterEntityUrl + { + Indices = new[] { 0, 17 }, + Url = "https://t.co/hoge", + DisplayUrl = "twitter.com/hoge/status/1…", + ExpandedUrl = "https://twitter.com/hoge/status/1234567890", + }, + }, + }; + status.QuotedStatus = null; + + var post = factory.CreateFromStatus(status, selfUserId: 100L, followerIds: EmptyIdSet); + + var accessibleText = "twitter.com/hoge/status/1…"; + Assert.Equal(accessibleText, post.AccessibleText); + Assert.Equal("twitter.com/hoge/status/1…", post.Text); + Assert.Equal("twitter.com/hoge/status/1…", post.TextFromApi); + Assert.Equal("twitter.com/hoge/status/1…", post.TextSingleLine); + } + + [Fact] + public void CreateHtmlAnchor_Test() + { + var text = "@twitterapi #BreakingMyTwitter https://t.co/mIJcSoVSK3"; + var entities = new TwitterEntities + { + UserMentions = new[] + { + new TwitterEntityMention { Indices = new[] { 0, 11 }, ScreenName = "twitterapi" }, + }, + Hashtags = new[] + { + new TwitterEntityHashtag { Indices = new[] { 12, 30 }, Text = "BreakingMyTwitter" }, + }, + Urls = new[] + { + new TwitterEntityUrl + { + Indices = new[] { 31, 54 }, + Url = "https://t.co/mIJcSoVSK3", + DisplayUrl = "apps-of-a-feather.com", + ExpandedUrl = "http://apps-of-a-feather.com/", + }, + }, + }; + + var expectedHtml = @"@twitterapi" + + @" #BreakingMyTwitter" + + @" apps-of-a-feather.com"; + + Assert.Equal(expectedHtml, TwitterPostFactory.CreateHtmlAnchor(text, entities, quotedStatusLink: null)); + } + + [Fact] + public void CreateHtmlAnchor_NicovideoTest() + { + var text = "sm9"; + var entities = new TwitterEntities(); + + var expectedHtml = @"sm9"; + + Assert.Equal(expectedHtml, TwitterPostFactory.CreateHtmlAnchor(text, entities, quotedStatusLink: null)); + } + + [Fact] + public void CreateHtmlAnchor_QuotedUrlWithPermelinkTest() + { + var text = "hoge"; + var entities = new TwitterEntities(); + var quotedStatusLink = new TwitterQuotedStatusPermalink + { + Url = "https://t.co/hoge", + Display = "twitter.com/hoge/status/1…", + Expanded = "https://twitter.com/hoge/status/1234567890", + }; + + var expectedHtml = @"hoge" + + @" twitter.com/hoge/status/1…"; + + Assert.Equal(expectedHtml, TwitterPostFactory.CreateHtmlAnchor(text, entities, quotedStatusLink)); + } + + [Fact] + public void ParseSource_Test() + { + var sourceHtml = "Twitter Web Client"; + + var expected = ("Twitter Web Client", new Uri("http://twitter.com/")); + Assert.Equal(expected, TwitterPostFactory.ParseSource(sourceHtml)); + } + + [Fact] + public void ParseSource_PlainTextTest() + { + var sourceHtml = "web"; + + var expected = ("web", (Uri?)null); + Assert.Equal(expected, TwitterPostFactory.ParseSource(sourceHtml)); + } + + [Fact] + public void ParseSource_RelativeUriTest() + { + // 参照: https://twitter.com/kim_upsilon/status/477796052049752064 + var sourceHtml = "erased_45416"; + + var expected = ("erased_45416", new Uri("https://twitter.com/erased_45416")); + Assert.Equal(expected, TwitterPostFactory.ParseSource(sourceHtml)); + } + + [Fact] + public void ParseSource_EmptyTest() + { + // 参照: https://twitter.com/kim_upsilon/status/595156014032244738 + var sourceHtml = ""; + + var expected = ("", (Uri?)null); + Assert.Equal(expected, TwitterPostFactory.ParseSource(sourceHtml)); + } + + [Fact] + public void ParseSource_NullTest() + { + string? sourceHtml = null; + + var expected = ("", (Uri?)null); + Assert.Equal(expected, TwitterPostFactory.ParseSource(sourceHtml)); + } + + [Fact] + public void ParseSource_UnescapeTest() + { + var sourceHtml = "<<hogehoge>>"; + + var expected = ("<>", new Uri("http://example.com/?aaa=123&bbb=456")); + Assert.Equal(expected, TwitterPostFactory.ParseSource(sourceHtml)); + } + + [Fact] + public void ParseSource_UnescapeNoUriTest() + { + var sourceHtml = "<<hogehoge>>"; + + var expected = ("<>", (Uri?)null); + Assert.Equal(expected, TwitterPostFactory.ParseSource(sourceHtml)); + } + + [Fact] + public void GetQuoteTweetStatusIds_EntityTest() + { + var entities = new[] + { + new TwitterEntityUrl + { + Url = "https://t.co/3HXq0LrbJb", + ExpandedUrl = "https://twitter.com/kim_upsilon/status/599261132361072640", + }, + }; + + var statusIds = TwitterPostFactory.GetQuoteTweetStatusIds(entities, quotedStatusLink: null); + Assert.Equal(new[] { 599261132361072640L }, statusIds); + } + + [Fact] + public void GetQuoteTweetStatusIds_QuotedStatusLinkTest() + { + var entities = new TwitterEntities(); + var quotedStatusLink = new TwitterQuotedStatusPermalink + { + Url = "https://t.co/3HXq0LrbJb", + Expanded = "https://twitter.com/kim_upsilon/status/599261132361072640", + }; + + var statusIds = TwitterPostFactory.GetQuoteTweetStatusIds(entities, quotedStatusLink); + Assert.Equal(new[] { 599261132361072640L }, statusIds); + } + + [Fact] + public void GetQuoteTweetStatusIds_UrlStringTest() + { + var urls = new[] + { + "https://twitter.com/kim_upsilon/status/599261132361072640", + }; + + var statusIds = TwitterPostFactory.GetQuoteTweetStatusIds(urls); + Assert.Equal(new[] { 599261132361072640L }, statusIds); + } + + [Fact] + public void GetQuoteTweetStatusIds_OverflowTest() + { + var urls = new[] + { + // 符号付き 64 ビット整数の範囲を超える値 + "https://twitter.com/kim_upsilon/status/9999999999999999999", + }; + + var statusIds = TwitterPostFactory.GetQuoteTweetStatusIds(urls); + Assert.Empty(statusIds); + } + } +} diff --git a/OpenTween.Tests/TwitterTest.cs b/OpenTween.Tests/TwitterTest.cs index 7da053a43..6794f178b 100644 --- a/OpenTween.Tests/TwitterTest.cs +++ b/OpenTween.Tests/TwitterTest.cs @@ -108,324 +108,6 @@ public void FindTopOfReplyChainTest() Assert.Equal(1210L, Twitter.FindTopOfReplyChain(posts, 1210L).StatusId); } - [Fact] - public void CreateAccessibleText_MediaAltTest() - { - var text = "https://t.co/hoge"; - var entities = new TwitterEntities - { - Media = new[] - { - new TwitterEntityMedia - { - Indices = new[] { 0, 17 }, - Url = "https://t.co/hoge", - DisplayUrl = "pic.twitter.com/hoge", - ExpandedUrl = "https://twitter.com/hoge/status/1234567890/photo/1", - AltText = "代替テキスト", - }, - }, - }; - - var expectedText = string.Format(Properties.Resources.ImageAltText, "代替テキスト"); - - Assert.Equal(expectedText, Twitter.CreateAccessibleText(text, entities, quotedStatus: null, quotedStatusLink: null)); - } - - [Fact] - public void CreateAccessibleText_MediaNoAltTest() - { - var text = "https://t.co/hoge"; - var entities = new TwitterEntities - { - Media = new[] - { - new TwitterEntityMedia - { - Indices = new[] { 0, 17 }, - Url = "https://t.co/hoge", - DisplayUrl = "pic.twitter.com/hoge", - ExpandedUrl = "https://twitter.com/hoge/status/1234567890/photo/1", - AltText = null, - }, - }, - }; - - var expectedText = "pic.twitter.com/hoge"; - - Assert.Equal(expectedText, Twitter.CreateAccessibleText(text, entities, quotedStatus: null, quotedStatusLink: null)); - } - - [Fact] - public void CreateAccessibleText_QuotedUrlTest() - { - var text = "https://t.co/hoge"; - var entities = new TwitterEntities - { - Urls = new[] - { - new TwitterEntityUrl - { - Indices = new[] { 0, 17 }, - Url = "https://t.co/hoge", - DisplayUrl = "twitter.com/hoge/status/1…", - ExpandedUrl = "https://twitter.com/hoge/status/1234567890", - }, - }, - }; - var quotedStatus = new TwitterStatus - { - Id = 1234567890L, - IdStr = "1234567890", - User = new TwitterUser - { - Id = 1111, - IdStr = "1111", - ScreenName = "foo", - }, - FullText = "test", - }; - - var expectedText = string.Format(Properties.Resources.QuoteStatus_AccessibleText, "foo", "test"); - - Assert.Equal(expectedText, Twitter.CreateAccessibleText(text, entities, quotedStatus, quotedStatusLink: null)); - } - - [Fact] - public void CreateAccessibleText_QuotedUrlWithPermelinkTest() - { - var text = "hoge"; - var entities = new TwitterEntities(); - var quotedStatus = new TwitterStatus - { - Id = 1234567890L, - IdStr = "1234567890", - User = new TwitterUser - { - Id = 1111, - IdStr = "1111", - ScreenName = "foo", - }, - FullText = "test", - }; - var quotedStatusLink = new TwitterQuotedStatusPermalink - { - Url = "https://t.co/hoge", - Display = "twitter.com/hoge/status/1…", - Expanded = "https://twitter.com/hoge/status/1234567890", - }; - - var expectedText = "hoge " + string.Format(Properties.Resources.QuoteStatus_AccessibleText, "foo", "test"); - - Assert.Equal(expectedText, Twitter.CreateAccessibleText(text, entities, quotedStatus, quotedStatusLink)); - } - - [Fact] - public void CreateAccessibleText_QuotedUrlNoReferenceTest() - { - var text = "https://t.co/hoge"; - var entities = new TwitterEntities - { - Urls = new[] - { - new TwitterEntityUrl - { - Indices = new[] { 0, 17 }, - Url = "https://t.co/hoge", - DisplayUrl = "twitter.com/hoge/status/1…", - ExpandedUrl = "https://twitter.com/hoge/status/1234567890", - }, - }, - }; - var quotedStatus = (TwitterStatus?)null; - - var expectedText = "twitter.com/hoge/status/1…"; - - Assert.Equal(expectedText, Twitter.CreateAccessibleText(text, entities, quotedStatus, quotedStatusLink: null)); - } - - [Fact] - public void CreateHtmlAnchor_Test() - { - var text = "@twitterapi #BreakingMyTwitter https://t.co/mIJcSoVSK3"; - var entities = new TwitterEntities - { - UserMentions = new[] - { - new TwitterEntityMention { Indices = new[] { 0, 11 }, ScreenName = "twitterapi" }, - }, - Hashtags = new[] - { - new TwitterEntityHashtag { Indices = new[] { 12, 30 }, Text = "BreakingMyTwitter" }, - }, - Urls = new[] - { - new TwitterEntityUrl - { - Indices = new[] { 31, 54 }, - Url = "https://t.co/mIJcSoVSK3", - DisplayUrl = "apps-of-a-feather.com", - ExpandedUrl = "http://apps-of-a-feather.com/", - }, - }, - }; - - var expectedHtml = @"@twitterapi" - + @" #BreakingMyTwitter" - + @" apps-of-a-feather.com"; - - Assert.Equal(expectedHtml, Twitter.CreateHtmlAnchor(text, entities, quotedStatusLink: null)); - } - - [Fact] - public void CreateHtmlAnchor_NicovideoTest() - { - var text = "sm9"; - var entities = new TwitterEntities(); - - var expectedHtml = @"sm9"; - - Assert.Equal(expectedHtml, Twitter.CreateHtmlAnchor(text, entities, quotedStatusLink: null)); - } - - [Fact] - public void CreateHtmlAnchor_QuotedUrlWithPermelinkTest() - { - var text = "hoge"; - var entities = new TwitterEntities(); - var quotedStatusLink = new TwitterQuotedStatusPermalink - { - Url = "https://t.co/hoge", - Display = "twitter.com/hoge/status/1…", - Expanded = "https://twitter.com/hoge/status/1234567890", - }; - - var expectedHtml = @"hoge" - + @" twitter.com/hoge/status/1…"; - - Assert.Equal(expectedHtml, Twitter.CreateHtmlAnchor(text, entities, quotedStatusLink)); - } - - [Fact] - public void ParseSource_Test() - { - var sourceHtml = "Twitter Web Client"; - - var expected = ("Twitter Web Client", new Uri("http://twitter.com/")); - Assert.Equal(expected, Twitter.ParseSource(sourceHtml)); - } - - [Fact] - public void ParseSource_PlainTextTest() - { - var sourceHtml = "web"; - - var expected = ("web", (Uri?)null); - Assert.Equal(expected, Twitter.ParseSource(sourceHtml)); - } - - [Fact] - public void ParseSource_RelativeUriTest() - { - // 参照: https://twitter.com/kim_upsilon/status/477796052049752064 - var sourceHtml = "erased_45416"; - - var expected = ("erased_45416", new Uri("https://twitter.com/erased_45416")); - Assert.Equal(expected, Twitter.ParseSource(sourceHtml)); - } - - [Fact] - public void ParseSource_EmptyTest() - { - // 参照: https://twitter.com/kim_upsilon/status/595156014032244738 - var sourceHtml = ""; - - var expected = ("", (Uri?)null); - Assert.Equal(expected, Twitter.ParseSource(sourceHtml)); - } - - [Fact] - public void ParseSource_NullTest() - { - string? sourceHtml = null; - - var expected = ("", (Uri?)null); - Assert.Equal(expected, Twitter.ParseSource(sourceHtml)); - } - - [Fact] - public void ParseSource_UnescapeTest() - { - var sourceHtml = "<<hogehoge>>"; - - var expected = ("<>", new Uri("http://example.com/?aaa=123&bbb=456")); - Assert.Equal(expected, Twitter.ParseSource(sourceHtml)); - } - - [Fact] - public void ParseSource_UnescapeNoUriTest() - { - var sourceHtml = "<<hogehoge>>"; - - var expected = ("<>", (Uri?)null); - Assert.Equal(expected, Twitter.ParseSource(sourceHtml)); - } - - [Fact] - public void GetQuoteTweetStatusIds_EntityTest() - { - var entities = new[] - { - new TwitterEntityUrl - { - Url = "https://t.co/3HXq0LrbJb", - ExpandedUrl = "https://twitter.com/kim_upsilon/status/599261132361072640", - }, - }; - - var statusIds = Twitter.GetQuoteTweetStatusIds(entities, quotedStatusLink: null); - Assert.Equal(new[] { 599261132361072640L }, statusIds); - } - - [Fact] - public void GetQuoteTweetStatusIds_QuotedStatusLinkTest() - { - var entities = new TwitterEntities(); - var quotedStatusLink = new TwitterQuotedStatusPermalink - { - Url = "https://t.co/3HXq0LrbJb", - Expanded = "https://twitter.com/kim_upsilon/status/599261132361072640", - }; - - var statusIds = Twitter.GetQuoteTweetStatusIds(entities, quotedStatusLink); - Assert.Equal(new[] { 599261132361072640L }, statusIds); - } - - [Fact] - public void GetQuoteTweetStatusIds_UrlStringTest() - { - var urls = new[] - { - "https://twitter.com/kim_upsilon/status/599261132361072640", - }; - - var statusIds = Twitter.GetQuoteTweetStatusIds(urls); - Assert.Equal(new[] { 599261132361072640L }, statusIds); - } - - [Fact] - public void GetQuoteTweetStatusIds_OverflowTest() - { - var urls = new[] - { - // 符号付き 64 ビット整数の範囲を超える値 - "https://twitter.com/kim_upsilon/status/9999999999999999999", - }; - - var statusIds = Twitter.GetQuoteTweetStatusIds(urls); - Assert.Empty(statusIds); - } - [Fact] public void GetApiResultCount_DefaultTest() { diff --git a/OpenTween/Models/PostClass.cs b/OpenTween/Models/PostClass.cs index b91ab0a69..e52e333f7 100644 --- a/OpenTween/Models/PostClass.cs +++ b/OpenTween/Models/PostClass.cs @@ -134,6 +134,8 @@ public string Text /// public class ExpandedUrlInfo : ICloneable { + public static bool AutoExpand { get; set; } = true; + /// 展開前の t.co ドメインの URL public string Url { get; } @@ -161,7 +163,7 @@ public ExpandedUrlInfo(string url, string expandedUrl, bool deepExpand) this.Url = url; this.expandedUrl = expandedUrl; - if (deepExpand) + if (AutoExpand && deepExpand) this.ExpandTask = this.DeepExpandAsync(); else this.ExpandTask = Task.CompletedTask; diff --git a/OpenTween/Models/TabInformations.cs b/OpenTween/Models/TabInformations.cs index a9769d3d5..1eac80f61 100644 --- a/OpenTween/Models/TabInformations.cs +++ b/OpenTween/Models/TabInformations.cs @@ -82,7 +82,7 @@ public IReadOnlyTabCollection Tabs // List private List lists = new(); - private TabInformations() + internal TabInformations() { } diff --git a/OpenTween/Models/TwitterPostFactory.cs b/OpenTween/Models/TwitterPostFactory.cs new file mode 100644 index 000000000..b792b4bda --- /dev/null +++ b/OpenTween/Models/TwitterPostFactory.cs @@ -0,0 +1,570 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +#nullable enable + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Text.RegularExpressions; +using OpenTween.Api.DataModel; + +namespace OpenTween.Models +{ + public class TwitterPostFactory + { + private static readonly Uri SourceUriBase = new("https://twitter.com/"); + + private readonly TabInformations tabinfo; + private readonly HashSet receivedHashTags = new(); + + public TwitterPostFactory(TabInformations tabinfo) + => this.tabinfo = tabinfo; + + public string[] GetReceivedHashtags() + { + lock (this.receivedHashTags) + { + var hashtags = this.receivedHashTags.ToArray(); + this.receivedHashTags.Clear(); + return hashtags; + } + } + + public PostClass CreateFromStatus( + TwitterStatus status, + long selfUserId, + ISet followerIds, + bool favTweet = false + ) + { + var post = new PostClass(); + TwitterEntities entities; + string sourceHtml; + + post.StatusId = status.Id; + if (status.RetweetedStatus != null) + { + var retweeted = status.RetweetedStatus; + + post.CreatedAt = MyCommon.DateTimeParse(retweeted.CreatedAt); + + // Id + post.RetweetedId = retweeted.Id; + // 本文 + post.TextFromApi = retweeted.FullText; + entities = retweeted.MergedEntities; + sourceHtml = retweeted.Source; + // Reply先 + post.InReplyToStatusId = retweeted.InReplyToStatusId; + post.InReplyToUser = retweeted.InReplyToScreenName; + post.InReplyToUserId = status.InReplyToUserId; + + if (favTweet) + { + post.IsFav = true; + } + else + { + // 幻覚fav対策 + var favTab = this.tabinfo.FavoriteTab; + post.IsFav = favTab.Contains(retweeted.Id); + } + + if (retweeted.Coordinates != null) + post.PostGeo = new PostClass.StatusGeo(retweeted.Coordinates.Coordinates[0], retweeted.Coordinates.Coordinates[1]); + + // 以下、ユーザー情報 + var user = retweeted.User; + if (user != null) + { + post.UserId = user.Id; + post.ScreenName = user.ScreenName; + post.Nickname = user.Name.Trim(); + post.ImageUrl = user.ProfileImageUrlHttps; + post.IsProtect = user.Protected; + } + else + { + post.UserId = 0L; + post.ScreenName = "?????"; + post.Nickname = "Unknown User"; + } + + // Retweetした人 + if (status.User != null) + { + post.RetweetedBy = status.User.ScreenName; + post.RetweetedByUserId = status.User.Id; + post.IsMe = post.RetweetedByUserId == selfUserId; + } + else + { + post.RetweetedBy = "?????"; + post.RetweetedByUserId = 0L; + } + } + else + { + post.CreatedAt = MyCommon.DateTimeParse(status.CreatedAt); + // 本文 + post.TextFromApi = status.FullText; + entities = status.MergedEntities; + sourceHtml = status.Source; + post.InReplyToStatusId = status.InReplyToStatusId; + post.InReplyToUser = status.InReplyToScreenName; + post.InReplyToUserId = status.InReplyToUserId; + + if (favTweet) + { + post.IsFav = true; + } + else + { + // 幻覚fav対策 + var favTab = this.tabinfo.FavoriteTab; + post.IsFav = favTab.Posts.TryGetValue(post.StatusId, out var tabinfoPost) && tabinfoPost.IsFav; + } + + if (status.Coordinates != null) + post.PostGeo = new PostClass.StatusGeo(status.Coordinates.Coordinates[0], status.Coordinates.Coordinates[1]); + + // 以下、ユーザー情報 + var user = status.User; + if (user != null) + { + post.UserId = user.Id; + post.ScreenName = user.ScreenName; + post.Nickname = user.Name.Trim(); + post.ImageUrl = user.ProfileImageUrlHttps; + post.IsProtect = user.Protected; + post.IsMe = post.UserId == selfUserId; + } + else + { + post.UserId = 0L; + post.ScreenName = "?????"; + post.Nickname = "Unknown User"; + } + } + // HTMLに整形 + var textFromApi = post.TextFromApi; + + var quotedStatusLink = (status.RetweetedStatus ?? status).QuotedStatusPermalink; + + if (quotedStatusLink != null && entities.Urls != null && entities.Urls.Any(x => x.ExpandedUrl == quotedStatusLink.Expanded)) + quotedStatusLink = null; // 移行期は entities.urls と quoted_status_permalink の両方に含まれる場合がある + + post.Text = CreateHtmlAnchor(textFromApi, entities, quotedStatusLink); + post.TextFromApi = textFromApi; + post.TextFromApi = this.ReplaceTextFromApi(post.TextFromApi, entities, quotedStatusLink); + post.TextFromApi = WebUtility.HtmlDecode(post.TextFromApi); + post.TextFromApi = post.TextFromApi.Replace("<3", "\u2661"); + post.AccessibleText = CreateAccessibleText(textFromApi, entities, (status.RetweetedStatus ?? status).QuotedStatus, quotedStatusLink); + post.AccessibleText = WebUtility.HtmlDecode(post.AccessibleText); + post.AccessibleText = post.AccessibleText.Replace("<3", "\u2661"); + + this.ExtractEntities(entities, post.ReplyToList, post.Media); + + post.QuoteStatusIds = GetQuoteTweetStatusIds(entities, quotedStatusLink) + .Where(x => x != post.StatusId && x != post.RetweetedId) + .Distinct().ToArray(); + + post.ExpandedUrls = entities.OfType() + .Select(x => new PostClass.ExpandedUrlInfo(x.Url, x.ExpandedUrl)) + .ToArray(); + + // メモリ使用量削減 (同一のテキストであれば同一の string インスタンスを参照させる) + if (post.Text == post.TextFromApi) + post.Text = post.TextFromApi; + if (post.AccessibleText == post.TextFromApi) + post.AccessibleText = post.TextFromApi; + + // 他の発言と重複しやすい (共通化できる) 文字列は string.Intern を通す + post.ScreenName = string.Intern(post.ScreenName); + post.Nickname = string.Intern(post.Nickname); + post.ImageUrl = string.Intern(post.ImageUrl); + post.RetweetedBy = post.RetweetedBy != null ? string.Intern(post.RetweetedBy) : null; + + // Source整形 + var (sourceText, sourceUri) = ParseSource(sourceHtml); + post.Source = string.Intern(sourceText); + post.SourceUri = sourceUri; + + post.IsReply = post.RetweetedId == null && post.ReplyToList.Any(x => x.UserId == selfUserId); + post.IsExcludeReply = false; + + if (post.IsMe) + { + post.IsOwl = false; + } + else + { + if (followerIds.Count > 0) + post.IsOwl = !followerIds.Contains(post.UserId); + } + + post.IsDm = false; + return post; + } + + public PostClass CreateFromDirectMessageEvent( + TwitterMessageEvent eventItem, + IReadOnlyDictionary users, + IReadOnlyDictionary apps, + long selfUserId + ) + { + var post = new PostClass(); + post.StatusId = long.Parse(eventItem.Id); + + var timestamp = long.Parse(eventItem.CreatedTimestamp); + post.CreatedAt = DateTimeUtc.UnixEpoch + TimeSpan.FromTicks(timestamp * TimeSpan.TicksPerMillisecond); + // 本文 + var textFromApi = eventItem.MessageCreate.MessageData.Text; + + var entities = eventItem.MessageCreate.MessageData.Entities; + var mediaEntity = eventItem.MessageCreate.MessageData.Attachment?.Media; + + if (mediaEntity != null) + entities.Media = new[] { mediaEntity }; + + // HTMLに整形 + post.Text = CreateHtmlAnchor(textFromApi, entities, quotedStatusLink: null); + post.TextFromApi = this.ReplaceTextFromApi(textFromApi, entities, quotedStatusLink: null); + post.TextFromApi = WebUtility.HtmlDecode(post.TextFromApi); + post.TextFromApi = post.TextFromApi.Replace("<3", "\u2661"); + post.AccessibleText = CreateAccessibleText(textFromApi, entities, quotedStatus: null, quotedStatusLink: null); + post.AccessibleText = WebUtility.HtmlDecode(post.AccessibleText); + post.AccessibleText = post.AccessibleText.Replace("<3", "\u2661"); + post.IsFav = false; + + this.ExtractEntities(entities, post.ReplyToList, post.Media); + + post.QuoteStatusIds = GetQuoteTweetStatusIds(entities, quotedStatusLink: null) + .Distinct().ToArray(); + + post.ExpandedUrls = entities.OfType() + .Select(x => new PostClass.ExpandedUrlInfo(x.Url, x.ExpandedUrl)) + .ToArray(); + + // 以下、ユーザー情報 + string userId; + if (eventItem.MessageCreate.SenderId != selfUserId.ToString(CultureInfo.InvariantCulture)) + { + userId = eventItem.MessageCreate.SenderId; + post.IsMe = false; + post.IsOwl = true; + } + else + { + userId = eventItem.MessageCreate.Target.RecipientId; + post.IsMe = true; + post.IsOwl = false; + } + + if (users.TryGetValue(userId, out var user)) + { + post.UserId = user.Id; + post.ScreenName = user.ScreenName; + post.Nickname = user.Name.Trim(); + post.ImageUrl = user.ProfileImageUrlHttps; + post.IsProtect = user.Protected; + } + else + { + post.UserId = 0L; + post.ScreenName = "?????"; + post.Nickname = "Unknown User"; + } + + // メモリ使用量削減 (同一のテキストであれば同一の string インスタンスを参照させる) + if (post.Text == post.TextFromApi) + post.Text = post.TextFromApi; + if (post.AccessibleText == post.TextFromApi) + post.AccessibleText = post.TextFromApi; + + // 他の発言と重複しやすい (共通化できる) 文字列は string.Intern を通す + post.ScreenName = string.Intern(post.ScreenName); + post.Nickname = string.Intern(post.Nickname); + post.ImageUrl = string.Intern(post.ImageUrl); + + var appId = eventItem.MessageCreate.SourceAppId; + if (appId != null && apps.TryGetValue(appId, out var app)) + { + post.Source = string.Intern(app.Name); + + try + { + post.SourceUri = new Uri(SourceUriBase, app.Url); + } + catch (UriFormatException) + { + } + } + + post.IsReply = false; + post.IsExcludeReply = false; + post.IsDm = true; + + return post; + } + + private string ReplaceTextFromApi(string text, TwitterEntities? entities, TwitterQuotedStatusPermalink? quotedStatusLink) + { + if (entities?.Urls != null) + { + foreach (var m in entities.Urls) + { + if (!MyCommon.IsNullOrEmpty(m.DisplayUrl)) + text = text.Replace(m.Url, m.DisplayUrl); + } + } + + if (entities?.Media != null) + { + foreach (var m in entities.Media) + { + if (!MyCommon.IsNullOrEmpty(m.DisplayUrl)) + text = text.Replace(m.Url, m.DisplayUrl); + } + } + + if (quotedStatusLink != null) + text += " " + quotedStatusLink.Display; + + return text; + } + + private void ExtractEntities(TwitterEntities? entities, List<(long UserId, string ScreenName)> atList, List media) + { + if (entities == null) + return; + + if (entities.Hashtags != null) + { + var hashtags = entities.Hashtags.Select(x => $"#{x.Text}"); + + lock (this.receivedHashTags) + this.receivedHashTags.UnionWith(hashtags); + } + + if (entities.UserMentions != null) + { + foreach (var ent in entities.UserMentions) + atList.Add((ent.Id, ent.ScreenName)); + } + + if (entities.Media != null) + { + if (media != null) + { + foreach (var ent in entities.Media) + { + if (media.Any(x => x.Url == ent.MediaUrlHttps)) + continue; + + var videoUrl = + ent.VideoInfo != null && ent.Type == "animated_gif" || ent.Type == "video" + ? ent.ExpandedUrl + : null; + + var mediaInfo = new MediaInfo(ent.MediaUrlHttps, ent.AltText, videoUrl); + media.Add(mediaInfo); + } + } + } + } + + private static string CreateAccessibleText(string text, TwitterEntities? entities, TwitterStatus? quotedStatus, TwitterQuotedStatusPermalink? quotedStatusLink) + { + if (entities == null) + return text; + + if (entities.Urls != null) + { + foreach (var entity in entities.Urls) + { + if (quotedStatus != null) + { + var matchStatusUrl = Twitter.StatusUrlRegex.Match(entity.ExpandedUrl); + if (matchStatusUrl.Success && matchStatusUrl.Groups["StatusId"].Value == quotedStatus.IdStr) + { + var quotedText = CreateAccessibleText(quotedStatus.FullText, quotedStatus.MergedEntities, quotedStatus: null, quotedStatusLink: null); + text = text.Replace(entity.Url, string.Format(Properties.Resources.QuoteStatus_AccessibleText, quotedStatus.User.ScreenName, quotedText)); + continue; + } + } + + if (!MyCommon.IsNullOrEmpty(entity.DisplayUrl)) + text = text.Replace(entity.Url, entity.DisplayUrl); + } + } + + if (entities.Media != null) + { + foreach (var entity in entities.Media) + { + if (!MyCommon.IsNullOrEmpty(entity.AltText)) + { + text = text.Replace(entity.Url, string.Format(Properties.Resources.ImageAltText, entity.AltText)); + } + else if (!MyCommon.IsNullOrEmpty(entity.DisplayUrl)) + { + text = text.Replace(entity.Url, entity.DisplayUrl); + } + } + } + + if (quotedStatus != null && quotedStatusLink != null) + { + var quoteText = CreateAccessibleText(quotedStatus.FullText, quotedStatus.MergedEntities, quotedStatus: null, quotedStatusLink: null); + text += " " + string.Format(Properties.Resources.QuoteStatus_AccessibleText, quotedStatus.User.ScreenName, quoteText); + } + + return text; + } + + internal static string CreateHtmlAnchor(string text, TwitterEntities entities, TwitterQuotedStatusPermalink? quotedStatusLink) + { + var mergedEntities = entities.Concat(TweetExtractor.ExtractEmojiEntities(text)); + + // PostClass.ExpandedUrlInfo を使用して非同期に URL 展開を行うためここでは expanded_url を使用しない + text = TweetFormatter.AutoLinkHtml(text, mergedEntities, keepTco: true); + + text = Regex.Replace(text, "(^|[^a-zA-Z0-9_/&##@@>=.~])(sm|nm)([0-9]{1,10})", "$1$2$3"); + text = PreProcessUrl(text); // IDN置換 + + if (quotedStatusLink != null) + { + text += string.Format(" {1}", + WebUtility.HtmlEncode(quotedStatusLink.Expanded), + WebUtility.HtmlEncode(quotedStatusLink.Display)); + } + + return text; + } + + private static string PreProcessUrl(string orgData) + { + int posl1; + var posl2 = 0; + var href = " -1) + { + // IDN展開 + posl1 = orgData.IndexOf(href, posl2, StringComparison.Ordinal); + posl1 += href.Length; + posl2 = orgData.IndexOf("\"", posl1, StringComparison.Ordinal); + var urlStr = orgData.Substring(posl1, posl2 - posl1); + + if (!urlStr.StartsWith("http://", StringComparison.Ordinal) + && !urlStr.StartsWith("https://", StringComparison.Ordinal) + && !urlStr.StartsWith("ftp://", StringComparison.Ordinal)) + { + continue; + } + + var replacedUrl = MyCommon.IDNEncode(urlStr); + if (replacedUrl == null) continue; + if (replacedUrl == urlStr) continue; + + orgData = orgData.Replace(" + /// Twitter APIから得たHTML形式のsource文字列を分析し、source名とURLに分離します + /// + public static (string SourceText, Uri? SourceUri) ParseSource(string? sourceHtml) + { + if (MyCommon.IsNullOrEmpty(sourceHtml)) + return ("", null); + + string sourceText; + Uri? sourceUri; + + // sourceHtmlの例: Twitter Web Client + + var match = Regex.Match(sourceHtml, "^.+?)\".*?>(?.+)$", RegexOptions.IgnoreCase); + if (match.Success) + { + sourceText = WebUtility.HtmlDecode(match.Groups["text"].Value); + try + { + var uriStr = WebUtility.HtmlDecode(match.Groups["uri"].Value); + sourceUri = new Uri(SourceUriBase, uriStr); + } + catch (UriFormatException) + { + sourceUri = null; + } + } + else + { + sourceText = WebUtility.HtmlDecode(sourceHtml); + sourceUri = null; + } + + return (sourceText, sourceUri); + } + + /// + /// ツイートに含まれる引用ツイートのURLからステータスIDを抽出 + /// + public static IEnumerable GetQuoteTweetStatusIds(IEnumerable? entities, TwitterQuotedStatusPermalink? quotedStatusLink) + { + entities ??= Enumerable.Empty(); + + var urls = entities.OfType().Select(x => x.ExpandedUrl); + + if (quotedStatusLink != null) + urls = urls.Append(quotedStatusLink.Expanded); + + return GetQuoteTweetStatusIds(urls); + } + + public static IEnumerable GetQuoteTweetStatusIds(IEnumerable urls) + { + foreach (var url in urls) + { + var match = Twitter.StatusUrlRegex.Match(url); + if (match.Success) + { + if (long.TryParse(match.Groups["StatusId"].Value, out var statusId)) + yield return statusId; + } + } + } + } +} diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 907c3e7d7..cb4691fdf 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -110,6 +110,7 @@ + diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 246894fab..1a0ae7dce 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -30,7 +30,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Globalization; using System.IO; using System.Linq; using System.Net; @@ -172,8 +171,7 @@ public class Twitter : IDisposable private ISet followerId = new HashSet(); private long[] noRTId = Array.Empty(); - // プロパティからアクセスされる共通情報 - private readonly List hashList = new(); + private readonly TwitterPostFactory postFactory; private string? nextCursorDirectMessage = null; @@ -181,6 +179,8 @@ public class Twitter : IDisposable public Twitter(TwitterApi api) { + this.postFactory = new(TabInformations.GetInstance()); + this.Api = api; this.Configuration = TwitterConfiguration.DefaultConfiguration(); this.TextConfiguration = TwitterTextConfiguration.DefaultConfiguration(); @@ -229,44 +229,6 @@ public void Initialize(string token, string tokenSecret, string username, long u this.Api.Initialize(token, tokenSecret, userId, username); } - internal static string PreProcessUrl(string orgData) - { - int posl1; - var posl2 = 0; - var href = " -1) - { - // IDN展開 - posl1 = orgData.IndexOf(href, posl2, StringComparison.Ordinal); - posl1 += href.Length; - posl2 = orgData.IndexOf("\"", posl1, StringComparison.Ordinal); - var urlStr = orgData.Substring(posl1, posl2 - posl1); - - if (!urlStr.StartsWith("http://", StringComparison.Ordinal) - && !urlStr.StartsWith("https://", StringComparison.Ordinal) - && !urlStr.StartsWith("ftp://", StringComparison.Ordinal)) - { - continue; - } - - var replacedUrl = MyCommon.IDNEncode(urlStr); - if (replacedUrl == null) continue; - if (replacedUrl == urlStr) continue; - - orgData = orgData.Replace(" PostStatus(PostStatusParams param) { this.CheckAccountState(); @@ -653,206 +615,10 @@ public async Task GetStatusApi(bool read, long id, TabModel tab) } private PostClass CreatePostsFromStatusData(TwitterStatus status) - => this.CreatePostsFromStatusData(status, false); + => this.CreatePostsFromStatusData(status, favTweet: false); private PostClass CreatePostsFromStatusData(TwitterStatus status, bool favTweet) - { - var post = new PostClass(); - TwitterEntities entities; - string sourceHtml; - - post.StatusId = status.Id; - if (status.RetweetedStatus != null) - { - var retweeted = status.RetweetedStatus; - - post.CreatedAt = MyCommon.DateTimeParse(retweeted.CreatedAt); - - // Id - post.RetweetedId = retweeted.Id; - // 本文 - post.TextFromApi = retweeted.FullText; - entities = retweeted.MergedEntities; - sourceHtml = retweeted.Source; - // Reply先 - post.InReplyToStatusId = retweeted.InReplyToStatusId; - post.InReplyToUser = retweeted.InReplyToScreenName; - post.InReplyToUserId = status.InReplyToUserId; - - if (favTweet) - { - post.IsFav = true; - } - else - { - // 幻覚fav対策 - var tc = TabInformations.GetInstance().FavoriteTab; - post.IsFav = tc.Contains(retweeted.Id); - } - - if (retweeted.Coordinates != null) - post.PostGeo = new PostClass.StatusGeo(retweeted.Coordinates.Coordinates[0], retweeted.Coordinates.Coordinates[1]); - - // 以下、ユーザー情報 - var user = retweeted.User; - if (user != null) - { - post.UserId = user.Id; - post.ScreenName = user.ScreenName; - post.Nickname = user.Name.Trim(); - post.ImageUrl = user.ProfileImageUrlHttps; - post.IsProtect = user.Protected; - } - else - { - post.UserId = 0L; - post.ScreenName = "?????"; - post.Nickname = "Unknown User"; - } - - // Retweetした人 - if (status.User != null) - { - post.RetweetedBy = status.User.ScreenName; - post.RetweetedByUserId = status.User.Id; - post.IsMe = post.RetweetedByUserId == this.UserId; - } - else - { - post.RetweetedBy = "?????"; - post.RetweetedByUserId = 0L; - } - } - else - { - post.CreatedAt = MyCommon.DateTimeParse(status.CreatedAt); - // 本文 - post.TextFromApi = status.FullText; - entities = status.MergedEntities; - sourceHtml = status.Source; - post.InReplyToStatusId = status.InReplyToStatusId; - post.InReplyToUser = status.InReplyToScreenName; - post.InReplyToUserId = status.InReplyToUserId; - - if (favTweet) - { - post.IsFav = true; - } - else - { - // 幻覚fav対策 - var tc = TabInformations.GetInstance().FavoriteTab; - post.IsFav = tc.Posts.TryGetValue(post.StatusId, out var tabinfoPost) && tabinfoPost.IsFav; - } - - if (status.Coordinates != null) - post.PostGeo = new PostClass.StatusGeo(status.Coordinates.Coordinates[0], status.Coordinates.Coordinates[1]); - - // 以下、ユーザー情報 - var user = status.User; - if (user != null) - { - post.UserId = user.Id; - post.ScreenName = user.ScreenName; - post.Nickname = user.Name.Trim(); - post.ImageUrl = user.ProfileImageUrlHttps; - post.IsProtect = user.Protected; - post.IsMe = post.UserId == this.UserId; - } - else - { - post.UserId = 0L; - post.ScreenName = "?????"; - post.Nickname = "Unknown User"; - } - } - // HTMLに整形 - var textFromApi = post.TextFromApi; - - var quotedStatusLink = (status.RetweetedStatus ?? status).QuotedStatusPermalink; - - if (quotedStatusLink != null && entities.Urls.Any(x => x.ExpandedUrl == quotedStatusLink.Expanded)) - quotedStatusLink = null; // 移行期は entities.urls と quoted_status_permalink の両方に含まれる場合がある - - post.Text = CreateHtmlAnchor(textFromApi, entities, quotedStatusLink); - post.TextFromApi = textFromApi; - post.TextFromApi = this.ReplaceTextFromApi(post.TextFromApi, entities, quotedStatusLink); - post.TextFromApi = WebUtility.HtmlDecode(post.TextFromApi); - post.TextFromApi = post.TextFromApi.Replace("<3", "\u2661"); - post.AccessibleText = CreateAccessibleText(textFromApi, entities, (status.RetweetedStatus ?? status).QuotedStatus, quotedStatusLink); - post.AccessibleText = WebUtility.HtmlDecode(post.AccessibleText); - post.AccessibleText = post.AccessibleText.Replace("<3", "\u2661"); - - this.ExtractEntities(entities, post.ReplyToList, post.Media); - - post.QuoteStatusIds = GetQuoteTweetStatusIds(entities, quotedStatusLink) - .Where(x => x != post.StatusId && x != post.RetweetedId) - .Distinct().ToArray(); - - post.ExpandedUrls = entities.OfType() - .Select(x => new PostClass.ExpandedUrlInfo(x.Url, x.ExpandedUrl)) - .ToArray(); - - // メモリ使用量削減 (同一のテキストであれば同一の string インスタンスを参照させる) - if (post.Text == post.TextFromApi) - post.Text = post.TextFromApi; - if (post.AccessibleText == post.TextFromApi) - post.AccessibleText = post.TextFromApi; - - // 他の発言と重複しやすい (共通化できる) 文字列は string.Intern を通す - post.ScreenName = string.Intern(post.ScreenName); - post.Nickname = string.Intern(post.Nickname); - post.ImageUrl = string.Intern(post.ImageUrl); - post.RetweetedBy = post.RetweetedBy != null ? string.Intern(post.RetweetedBy) : null; - - // Source整形 - var (sourceText, sourceUri) = ParseSource(sourceHtml); - post.Source = string.Intern(sourceText); - post.SourceUri = sourceUri; - - post.IsReply = post.RetweetedId == null && post.ReplyToList.Any(x => x.UserId == this.UserId); - post.IsExcludeReply = false; - - if (post.IsMe) - { - post.IsOwl = false; - } - else - { - if (this.followerId.Count > 0) post.IsOwl = !this.followerId.Contains(post.UserId); - } - - post.IsDm = false; - return post; - } - - /// - /// ツイートに含まれる引用ツイートのURLからステータスIDを抽出 - /// - public static IEnumerable GetQuoteTweetStatusIds(IEnumerable? entities, TwitterQuotedStatusPermalink? quotedStatusLink) - { - entities ??= Enumerable.Empty(); - - var urls = entities.OfType().Select(x => x.ExpandedUrl); - - if (quotedStatusLink != null) - urls = urls.Append(quotedStatusLink.Expanded); - - return GetQuoteTweetStatusIds(urls); - } - - public static IEnumerable GetQuoteTweetStatusIds(IEnumerable urls) - { - foreach (var url in urls) - { - var match = Twitter.StatusUrlRegex.Match(url); - if (match.Success) - { - if (long.TryParse(match.Groups["StatusId"].Value, out var statusId)) - yield return statusId; - } - } - } + => this.postFactory.CreateFromStatus(status, this.UserId, this.followerId, favTweet); private long? CreatePostsFromJson(TwitterStatus[] items, MyCommon.WORKERTYPE gType, TabModel? tab, bool read) { @@ -1226,98 +992,16 @@ private void CreateDirectMessagesEventFromJson( IReadOnlyDictionary apps, bool read) { + var dmTab = TabInformations.GetInstance().DirectMessageTab; + foreach (var eventItem in events) { - var post = new PostClass(); - post.StatusId = long.Parse(eventItem.Id); - - var timestamp = long.Parse(eventItem.CreatedTimestamp); - post.CreatedAt = DateTimeUtc.UnixEpoch + TimeSpan.FromTicks(timestamp * TimeSpan.TicksPerMillisecond); - // 本文 - var textFromApi = eventItem.MessageCreate.MessageData.Text; - - var entities = eventItem.MessageCreate.MessageData.Entities; - var mediaEntity = eventItem.MessageCreate.MessageData.Attachment?.Media; - - if (mediaEntity != null) - entities.Media = new[] { mediaEntity }; - - // HTMLに整形 - post.Text = CreateHtmlAnchor(textFromApi, entities, quotedStatusLink: null); - post.TextFromApi = this.ReplaceTextFromApi(textFromApi, entities, quotedStatusLink: null); - post.TextFromApi = WebUtility.HtmlDecode(post.TextFromApi); - post.TextFromApi = post.TextFromApi.Replace("<3", "\u2661"); - post.AccessibleText = CreateAccessibleText(textFromApi, entities, quotedStatus: null, quotedStatusLink: null); - post.AccessibleText = WebUtility.HtmlDecode(post.AccessibleText); - post.AccessibleText = post.AccessibleText.Replace("<3", "\u2661"); - post.IsFav = false; - - this.ExtractEntities(entities, post.ReplyToList, post.Media); - - post.QuoteStatusIds = GetQuoteTweetStatusIds(entities, quotedStatusLink: null) - .Distinct().ToArray(); - - post.ExpandedUrls = entities.OfType() - .Select(x => new PostClass.ExpandedUrlInfo(x.Url, x.ExpandedUrl)) - .ToArray(); - - // 以下、ユーザー情報 - string userId; - if (eventItem.MessageCreate.SenderId != this.Api.CurrentUserId.ToString(CultureInfo.InvariantCulture)) - { - userId = eventItem.MessageCreate.SenderId; - post.IsMe = false; - post.IsOwl = true; - } - else - { - userId = eventItem.MessageCreate.Target.RecipientId; - post.IsMe = true; - post.IsOwl = false; - } - - if (!users.TryGetValue(userId, out var user)) - continue; - - post.UserId = user.Id; - post.ScreenName = user.ScreenName; - post.Nickname = user.Name.Trim(); - post.ImageUrl = user.ProfileImageUrlHttps; - post.IsProtect = user.Protected; - - // メモリ使用量削減 (同一のテキストであれば同一の string インスタンスを参照させる) - if (post.Text == post.TextFromApi) - post.Text = post.TextFromApi; - if (post.AccessibleText == post.TextFromApi) - post.AccessibleText = post.TextFromApi; - - // 他の発言と重複しやすい (共通化できる) 文字列は string.Intern を通す - post.ScreenName = string.Intern(post.ScreenName); - post.Nickname = string.Intern(post.Nickname); - post.ImageUrl = string.Intern(post.ImageUrl); - - var appId = eventItem.MessageCreate.SourceAppId; - if (appId != null && apps.TryGetValue(appId, out var app)) - { - post.Source = string.Intern(app.Name); - - try - { - post.SourceUri = new Uri(SourceUriBase, app.Url); - } - catch (UriFormatException) - { - } - } + var post = this.postFactory.CreateFromDirectMessageEvent(eventItem, users, apps, this.UserId); post.IsRead = read; if (post.IsMe && !read && this.ReadOwnPost) post.IsRead = true; - post.IsReply = false; - post.IsExcludeReply = false; - post.IsDm = true; - var dmTab = TabInformations.GetInstance().DirectMessageTab; dmTab.AddPostQueue(post); } } @@ -1346,81 +1030,6 @@ public async Task GetFavoritesApi(bool read, FavoritesTabModel tab, bool backwar tab.OldestId = minimumId.Value; } - private string ReplaceTextFromApi(string text, TwitterEntities? entities, TwitterQuotedStatusPermalink? quotedStatusLink) - { - if (entities != null) - { - if (entities.Urls != null) - { - foreach (var m in entities.Urls) - { - if (!MyCommon.IsNullOrEmpty(m.DisplayUrl)) text = text.Replace(m.Url, m.DisplayUrl); - } - } - if (entities.Media != null) - { - foreach (var m in entities.Media) - { - if (!MyCommon.IsNullOrEmpty(m.DisplayUrl)) text = text.Replace(m.Url, m.DisplayUrl); - } - } - } - - if (quotedStatusLink != null) - text += " " + quotedStatusLink.Display; - - return text; - } - - internal static string CreateAccessibleText(string text, TwitterEntities? entities, TwitterStatus? quotedStatus, TwitterQuotedStatusPermalink? quotedStatusLink) - { - if (entities == null) - return text; - - if (entities.Urls != null) - { - foreach (var entity in entities.Urls) - { - if (quotedStatus != null) - { - var matchStatusUrl = Twitter.StatusUrlRegex.Match(entity.ExpandedUrl); - if (matchStatusUrl.Success && matchStatusUrl.Groups["StatusId"].Value == quotedStatus.IdStr) - { - var quotedText = CreateAccessibleText(quotedStatus.FullText, quotedStatus.MergedEntities, quotedStatus: null, quotedStatusLink: null); - text = text.Replace(entity.Url, string.Format(Properties.Resources.QuoteStatus_AccessibleText, quotedStatus.User.ScreenName, quotedText)); - continue; - } - } - - if (!MyCommon.IsNullOrEmpty(entity.DisplayUrl)) - text = text.Replace(entity.Url, entity.DisplayUrl); - } - } - - if (entities.Media != null) - { - foreach (var entity in entities.Media) - { - if (!MyCommon.IsNullOrEmpty(entity.AltText)) - { - text = text.Replace(entity.Url, string.Format(Properties.Resources.ImageAltText, entity.AltText)); - } - else if (!MyCommon.IsNullOrEmpty(entity.DisplayUrl)) - { - text = text.Replace(entity.Url, entity.DisplayUrl); - } - } - } - - if (quotedStatus != null && quotedStatusLink != null) - { - var quoteText = CreateAccessibleText(quotedStatus.FullText, quotedStatus.MergedEntities, quotedStatus: null, quotedStatusLink: null); - text += " " + string.Format(Properties.Resources.QuoteStatus_AccessibleText, quotedStatus.User.ScreenName, quoteText); - } - - return text; - } - /// /// フォロワーIDを更新します /// @@ -1561,106 +1170,6 @@ await this.Api.ListsMembersShow(listId, user) } } - private void ExtractEntities(TwitterEntities? entities, List<(long UserId, string ScreenName)> atList, List media) - { - if (entities != null) - { - if (entities.Hashtags != null) - { - lock (this.lockObj) - { - this.hashList.AddRange(entities.Hashtags.Select(x => "#" + x.Text)); - } - } - if (entities.UserMentions != null) - { - foreach (var ent in entities.UserMentions) - { - atList.Add((ent.Id, ent.ScreenName)); - } - } - if (entities.Media != null) - { - if (media != null) - { - foreach (var ent in entities.Media) - { - if (!media.Any(x => x.Url == ent.MediaUrlHttps)) - { - if (ent.VideoInfo != null && - ent.Type == "animated_gif" || ent.Type == "video") - { - media.Add(new MediaInfo(ent.MediaUrlHttps, ent.AltText, ent.ExpandedUrl)); - } - else - { - media.Add(new MediaInfo(ent.MediaUrlHttps, ent.AltText, videoUrl: null)); - } - } - } - } - } - } - } - - internal static string CreateHtmlAnchor(string text, TwitterEntities? entities, TwitterQuotedStatusPermalink? quotedStatusLink) - { - var mergedEntities = entities.Concat(TweetExtractor.ExtractEmojiEntities(text)); - - // PostClass.ExpandedUrlInfo を使用して非同期に URL 展開を行うためここでは expanded_url を使用しない - text = TweetFormatter.AutoLinkHtml(text, mergedEntities, keepTco: true); - - text = Regex.Replace(text, "(^|[^a-zA-Z0-9_/&##@@>=.~])(sm|nm)([0-9]{1,10})", "$1$2$3"); - text = PreProcessUrl(text); // IDN置換 - - if (quotedStatusLink != null) - { - text += string.Format(" {1}", - WebUtility.HtmlEncode(quotedStatusLink.Url), - WebUtility.HtmlEncode(quotedStatusLink.Display)); - } - - return text; - } - - private static readonly Uri SourceUriBase = new("https://twitter.com/"); - - /// - /// Twitter APIから得たHTML形式のsource文字列を分析し、source名とURLに分離します - /// - internal static (string SourceText, Uri? SourceUri) ParseSource(string? sourceHtml) - { - if (MyCommon.IsNullOrEmpty(sourceHtml)) - return ("", null); - - string sourceText; - Uri? sourceUri; - - // sourceHtmlの例: Twitter Web Client - - var match = Regex.Match(sourceHtml, "^.+?)\".*?>(?.+)$", RegexOptions.IgnoreCase); - if (match.Success) - { - sourceText = WebUtility.HtmlDecode(match.Groups["text"].Value); - try - { - var uriStr = WebUtility.HtmlDecode(match.Groups["uri"].Value); - sourceUri = new Uri(SourceUriBase, uriStr); - } - catch (UriFormatException) - { - sourceUri = null; - } - } - else - { - sourceText = WebUtility.HtmlDecode(sourceHtml); - sourceUri = null; - } - - return (sourceText, sourceUri); - } - public async Task GetInfoApi() { if (Twitter.AccountState != MyCommon.ACCOUNT_STATE.Valid) return null; @@ -1716,15 +1225,7 @@ public async Task RefreshMuteUserIdsAsync() } public string[] GetHashList() - { - string[] hashArray; - lock (this.lockObj) - { - hashArray = this.hashList.ToArray(); - this.hashList.Clear(); - } - return hashArray; - } + => this.postFactory.GetReceivedHashtags(); public string AccessToken => ((TwitterApiConnection)this.Api.Connection).AccessToken; From 2ce03b008fd6c504033697e56835a7763667dd41 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 29 May 2022 08:13:53 +0900 Subject: [PATCH 205/402] =?UTF-8?q?=E6=8A=95=E7=A8=BF=E6=99=82=E5=8F=96?= =?UTF-8?q?=E5=BE=97=E3=81=AE=E8=A8=AD=E5=AE=9A=E3=81=AB=E9=96=A2=E3=82=8F?= =?UTF-8?q?=E3=82=89=E3=81=9A=E6=8A=95=E7=A8=BF=E3=81=97=E3=81=9F=E7=99=BA?= =?UTF-8?q?=E8=A8=80=E3=82=92=E7=9B=B4=E3=81=A1=E3=81=ABRecent=E3=82=BF?= =?UTF-8?q?=E3=83=96=E3=81=AB=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit API v2 ではホームタイムラインが若干遅延しており、投稿直後に取得してもその発言が含まれていない場合があるため --- OpenTween/Tween.cs | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 6292d5ff8..02bc23a78 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -1779,19 +1779,15 @@ await Task.Run(async () => this.SetMainWindowTitle(); // TLに反映 - if (this.settings.Common.PostAndGet) - { - await this.RefreshTabAsync(); - } - else + if (post != null) { - if (post != null) - { - this.statuses.AddPost(post); - this.statuses.DistributePosts(); - } + this.statuses.AddPost(post); + this.statuses.DistributePosts(); this.RefreshTimeline(); } + + if (this.settings.Common.PostAndGet) + await this.RefreshTabAsync(); } private async Task RetweetAsync(IReadOnlyList statusIds) From 1600fe791349791549255a87cf19b1ae31d37855 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 9 Jul 2022 23:05:41 +0900 Subject: [PATCH 206/402] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=96=93=E9=9A=94?= =?UTF-8?q?=E3=81=AE=E6=9C=80=E5=B0=8F=E5=80=A4=E3=82=9215=E7=A7=92?= =?UTF-8?q?=E4=BB=A5=E4=B8=8A=E3=81=A8=E3=81=99=E3=82=8B=E5=88=B6=E9=99=90?= =?UTF-8?q?=E3=82=92=E5=BB=83=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ホームタイムラインのレートリミットが 180回/15分 となったことで 5 秒間隔の更新が可能になったため緩和した。 レートリミットの超過を検知した場合はその後のリクエストの送信が抑制される挙動となっている。 --- OpenTween/ApplicationEvents.cs | 3 +- OpenTween/Properties/Resources.Designer.cs | 47 +-------- OpenTween/Properties/Resources.en.resx | 7 +- OpenTween/Properties/Resources.resx | 7 +- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Setting/Panel/GetPeriodPanel.cs | 106 ++++----------------- OpenTween/Setting/SettingCommon.cs | 29 +++--- 7 files changed, 38 insertions(+), 162 deletions(-) diff --git a/OpenTween/ApplicationEvents.cs b/OpenTween/ApplicationEvents.cs index 4946bcf9c..39e75494d 100644 --- a/OpenTween/ApplicationEvents.cs +++ b/OpenTween/ApplicationEvents.cs @@ -67,8 +67,7 @@ public static int Main(string[] args) using var container = new ApplicationContainer(settings); - var noLimit = StartupOptions.ContainsKey("nolimit"); - settings.Common.Validate(noLimit); + settings.Common.Validate(); ThemeManager.ApplyGlobalUIFont(settings.Local); container.CultureService.Initialize(); diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 495820507..a282f0ad6 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -856,24 +856,6 @@ internal static string Disabled { } } - /// - /// 更新間隔には数値(0または15~6000)を指定してください。 に類似しているローカライズされた文字列を検索します。 - /// - internal static string DMPeriod_ValidatingText1 { - get { - return ResourceManager.GetString("DMPeriod_ValidatingText1", resourceCulture); - } - } - - /// - /// 更新間隔には数値(0または15~6000)を指定してください。 に類似しているローカライズされた文字列を検索します。 - /// - internal static string DMPeriod_ValidatingText2 { - get { - return ResourceManager.GetString("DMPeriod_ValidatingText2", resourceCulture); - } - } - /// /// プロフィール取得中・・・ に類似しているローカライズされた文字列を検索します。 /// @@ -2029,24 +2011,6 @@ internal static string PostWorker_RunWorkerCompletedText5 { } } - /// - /// 更新間隔には数値(0または30~6000)を指定してください。 に類似しているローカライズされた文字列を検索します。 - /// - internal static string PubSearchPeriod_ValidatingText1 { - get { - return ResourceManager.GetString("PubSearchPeriod_ValidatingText1", resourceCulture); - } - } - - /// - /// 更新間隔には数値(0または30~6000)を指定してください。 に類似しているローカライズされた文字列を検索します。 - /// - internal static string PubSearchPeriod_ValidatingText2 { - get { - return ResourceManager.GetString("PubSearchPeriod_ValidatingText2", resourceCulture); - } - } - /// /// [引用 @{0}: {1}] に類似しているローカライズされた文字列を検索します。 /// @@ -2939,7 +2903,7 @@ internal static string TextSearchCountApi_Validating1 { } /// - /// 更新間隔には数値(0または15~6000)を指定してください。 に類似しているローカライズされた文字列を検索します。 + /// 更新間隔には 0 以上の数値を指定してください。 に類似しているローカライズされた文字列を検索します。 /// internal static string TimelinePeriod_ValidatingText1 { get { @@ -2947,15 +2911,6 @@ internal static string TimelinePeriod_ValidatingText1 { } } - /// - /// 更新間隔には数値(0または15~6000)を指定してください。 に類似しているローカライズされた文字列を検索します。 - /// - internal static string TimelinePeriod_ValidatingText2 { - get { - return ResourceManager.GetString("TimelinePeriod_ValidatingText2", resourceCulture); - } - } - /// /// DMRcv更新中... に類似しているローカライズされた文字列を検索します。 /// diff --git a/OpenTween/Properties/Resources.en.resx b/OpenTween/Properties/Resources.en.resx index 850c2d0de..08305d6dd 100644 --- a/OpenTween/Properties/Resources.en.resx +++ b/OpenTween/Properties/Resources.en.resx @@ -84,8 +84,6 @@ Remove succeeded Disable Disabled - Fetching interval must a value in 0 or 15 to 6000. - Fetching interval must a value in 0 or 15 to 6000. Now getting the profile... Invalid regular expression pattern. No matches found. @@ -201,8 +199,6 @@ Available service: {1} none POST completed Recent refreshing... - Fetching interval must a value in 0 or 30 to 6000. - Fetching interval must a value in 0 or 30 to 6000. [Quote @{0}: {1}] Please do Authentication processing to get/send Direct Messages again. Recent refreshing... @@ -303,8 +299,7 @@ Do you retry to update status? Port number must be integer number. Port number must be number 0 to 65535. Getting number of tweet in Api-mode must be 20 to 100. - Refresh interval must be number 0 or 15 to 6000 - Refresh interval must be number 0 or 15 to 6000 + Refresh interval must be number greater than or equal to 0. DMRcv refreshing... Recent refreshing... Please send this file to {0}. diff --git a/OpenTween/Properties/Resources.resx b/OpenTween/Properties/Resources.resx index cbea09bfa..c0bcedc00 100644 --- a/OpenTween/Properties/Resources.resx +++ b/OpenTween/Properties/Resources.resx @@ -91,8 +91,6 @@ ..\Resources\Description.txt;System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 無効化 無効 - 更新間隔には数値(0または15~6000)を指定してください。 - 更新間隔には数値(0または15~6000)を指定してください。 プロフィール取得中・・・ 正規表現パターンが間違っています。 検索条件に一致するデータは見つかりません。 @@ -228,8 +226,6 @@ ..\Resources\S14.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a POST完了 Recent更新中... - 更新間隔には数値(0または30~6000)を指定してください。 - 更新間隔には数値(0または30~6000)を指定してください。 [引用 @{0}: {1}] Direct Messageの送受信をするため、もう一度認証処理をして下さい。 ..\Resources\re.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -338,8 +334,7 @@ ポート番号には整数値を指定してください。 ポート番号には0~65535を指定してください。 取得発言数は20~100件を指定してください。 - 更新間隔には数値(0または15~6000)を指定してください。 - 更新間隔には数値(0または15~6000)を指定してください。 + 更新間隔には 0 以上の数値を指定してください。 DMRcv更新中... Recent更新中... このファイルの内容を {0} まで送っていただけると助かります。 diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 3d1d92696..49b731006 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -16,6 +16,7 @@ * CHG: 複数のユーザー宛のリプライ時にツイートの先頭にピリオドを加える仕様を廃止 * CHG: 発言一覧上でEnterキーを押した時の動作をダブルクリック時と同じとなるように変更 * CHG: 初回起動時のウィンドウサイズなどの初期値を変更 + * CHG: 更新間隔の最小値を15秒以上とする制限を廃止 * FIX: 「Twitter API稼働状況」のリンク先を修正 (thx @kzlogos!) * FIX: 起動時に読み込まれた検索・リストタブでフォロー状態を表す色が反映されない不具合を修正 (thx @Hawklaver!) * FIX: 等幅フォント表示を有効にした場合に背景色の設定が全面に適用されない不具合を修正 (thx @StoutAmmo!) diff --git a/OpenTween/Setting/Panel/GetPeriodPanel.cs b/OpenTween/Setting/Panel/GetPeriodPanel.cs index 3a4afb861..bf099b689 100644 --- a/OpenTween/Setting/Panel/GetPeriodPanel.cs +++ b/OpenTween/Setting/Panel/GetPeriodPanel.cs @@ -116,133 +116,67 @@ public void SaveConfig(SettingCommon settingCommon) private void TimelinePeriod_Validating(object sender, CancelEventArgs e) { - int prd; - try - { - prd = int.Parse(this.TimelinePeriod.Text); - } - catch (Exception) + if (!this.ValidateIntervalStr(this.TimelinePeriod.Text)) { MessageBox.Show(Properties.Resources.TimelinePeriod_ValidatingText1); e.Cancel = true; - return; - } - - if (prd != 0 && (prd < 15 || prd > 6000)) - { - MessageBox.Show(Properties.Resources.TimelinePeriod_ValidatingText2); - e.Cancel = true; - return; } } private void ReplyPeriod_Validating(object sender, CancelEventArgs e) { - int prd; - try - { - prd = int.Parse(this.ReplyPeriod.Text); - } - catch (Exception) + if (!this.ValidateIntervalStr(this.ReplyPeriod.Text)) { MessageBox.Show(Properties.Resources.TimelinePeriod_ValidatingText1); e.Cancel = true; - return; - } - - if (prd != 0 && (prd < 15 || prd > 6000)) - { - MessageBox.Show(Properties.Resources.TimelinePeriod_ValidatingText2); - e.Cancel = true; - return; } } private void DMPeriod_Validating(object sender, CancelEventArgs e) { - int prd; - try - { - prd = int.Parse(this.DMPeriod.Text); - } - catch (Exception) + if (!this.ValidateIntervalStr(this.DMPeriod.Text)) { - MessageBox.Show(Properties.Resources.DMPeriod_ValidatingText1); - e.Cancel = true; - return; - } - - if (prd != 0 && (prd < 15 || prd > 6000)) - { - MessageBox.Show(Properties.Resources.DMPeriod_ValidatingText2); + MessageBox.Show(Properties.Resources.TimelinePeriod_ValidatingText1); e.Cancel = true; - return; } } private void PubSearchPeriod_Validating(object sender, CancelEventArgs e) { - int prd; - try + if (!this.ValidateIntervalStr(this.PubSearchPeriod.Text)) { - prd = int.Parse(this.PubSearchPeriod.Text); - } - catch (Exception) - { - MessageBox.Show(Properties.Resources.PubSearchPeriod_ValidatingText1); - e.Cancel = true; - return; - } - - if (prd != 0 && (prd < 30 || prd > 6000)) - { - MessageBox.Show(Properties.Resources.PubSearchPeriod_ValidatingText2); + MessageBox.Show(Properties.Resources.TimelinePeriod_ValidatingText1); e.Cancel = true; } } private void ListsPeriod_Validating(object sender, CancelEventArgs e) { - int prd; - try - { - prd = int.Parse(this.ListsPeriod.Text); - } - catch (Exception) + if (!this.ValidateIntervalStr(this.ListsPeriod.Text)) { - MessageBox.Show(Properties.Resources.DMPeriod_ValidatingText1); - e.Cancel = true; - return; - } - - if (prd != 0 && (prd < 15 || prd > 6000)) - { - MessageBox.Show(Properties.Resources.DMPeriod_ValidatingText2); + MessageBox.Show(Properties.Resources.TimelinePeriod_ValidatingText1); e.Cancel = true; - return; } } private void UserTimeline_Validating(object sender, CancelEventArgs e) { - int prd; - try + if (!this.ValidateIntervalStr(this.UserTimelinePeriod.Text)) { - prd = int.Parse(this.UserTimelinePeriod.Text); - } - catch (Exception) - { - MessageBox.Show(Properties.Resources.DMPeriod_ValidatingText1); + MessageBox.Show(Properties.Resources.TimelinePeriod_ValidatingText1); e.Cancel = true; - return; } + } - if (prd != 0 && (prd < 15 || prd > 6000)) - { - MessageBox.Show(Properties.Resources.DMPeriod_ValidatingText2); - e.Cancel = true; - return; - } + private bool ValidateIntervalStr(string str) + { + if (!int.TryParse(str, out var value)) + return false; + + if (value < 0) + return false; + + return true; } } } diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index 895dce894..b16ebad13 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -261,28 +261,25 @@ public Version? SkipUpdateVersion [XmlElement(ElementName = nameof(SkipUpdateVersion))] public string SkipUpdateVersionStr { get; set; } = ""; - public void Validate(bool noLimit = false) + public void Validate() { - if (!noLimit) - { - if (this.TimelinePeriod < 15 && this.TimelinePeriod > 0) - this.TimelinePeriod = 15; + if (this.TimelinePeriod < 0) + this.TimelinePeriod = 15; - if (this.ReplyPeriod < 15 && this.ReplyPeriod > 0) - this.ReplyPeriod = 15; + if (this.ReplyPeriod < 0) + this.ReplyPeriod = 15; - if (this.DMPeriod < 15 && this.DMPeriod > 0) - this.DMPeriod = 15; + if (this.DMPeriod < 0) + this.DMPeriod = 15; - if (this.PubSearchPeriod < 30 && this.PubSearchPeriod > 0) - this.PubSearchPeriod = 30; + if (this.PubSearchPeriod < 0) + this.PubSearchPeriod = 30; - if (this.UserTimelinePeriod < 15 && this.UserTimelinePeriod > 0) - this.UserTimelinePeriod = 15; + if (this.UserTimelinePeriod < 0) + this.UserTimelinePeriod = 15; - if (this.ListsPeriod < 15 && this.ListsPeriod > 0) - this.ListsPeriod = 15; - } + if (this.ListsPeriod < 0) + this.ListsPeriod = 15; if (!Twitter.VerifyApiResultCount(MyCommon.WORKERTYPE.Timeline, this.CountApi)) this.CountApi = 60; From cf867226e81ca2d7d92496c9455b8339cc425b37 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 10 Jul 2022 14:05:29 +0900 Subject: [PATCH 207/402] =?UTF-8?q?Recent=E3=82=BF=E3=83=96=E3=81=AEAPI=20?= =?UTF-8?q?v2=E7=A7=BB=E8=A1=8C=E3=81=AB=E3=82=88=E3=82=8B=E5=8F=96?= =?UTF-8?q?=E5=BE=97=E4=BB=B6=E6=95=B0=E4=B8=8A=E9=99=90=E3=81=AE=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=82=92=E5=8F=8D=E6=98=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: e03de8b0 ("Recentタブのツイート取得にTwitter API v2を使用する") --- OpenTween.Tests/TwitterTest.cs | 2 +- OpenTween/Resources/ChangeLog.txt | 2 +- OpenTween/Twitter.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OpenTween.Tests/TwitterTest.cs b/OpenTween.Tests/TwitterTest.cs index 6794f178b..2c03f9698 100644 --- a/OpenTween.Tests/TwitterTest.cs +++ b/OpenTween.Tests/TwitterTest.cs @@ -166,7 +166,7 @@ public void GetApiResultCount_AdditionalCountTest() // Timeline Assert.Equal(timeline, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Timeline, false, false)); - Assert.Equal(more, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Timeline, true, false)); + Assert.Equal(100, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Timeline, true, false)); // 100 件が上限 Assert.Equal(startup, Twitter.GetApiResultCount(MyCommon.WORKERTYPE.Timeline, false, true)); // Reply diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 49b731006..820bc5ac7 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,7 +2,7 @@ ==== Ver 2.5.1-dev(2022/xx/xx) * NEW: Recentタブの発言の取得に Twitter API v2 を使用 - - 従来の API v1.1 と比べて、15分間に取得できる回数の制限が15→180回に緩和されます + - 従来の API v1.1 と比べて、15分間に取得できる回数の制限が15→180回に緩和、一度に取得できる件数が200→100件になります * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) * NEW: 発言詳細欄の名前やアイコンのクリックによるプロフィール表示に対応 * NEW: クリップボード経由での複数枚の画像ファイル添付に対応 diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 1a0ae7dce..1eab17e64 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -449,7 +449,7 @@ public static int GetMaxApiResultCount(MyCommon.WORKERTYPE type) // https://dev.twitter.com/rest/public return type switch { - MyCommon.WORKERTYPE.Timeline => 200, + MyCommon.WORKERTYPE.Timeline => 100, MyCommon.WORKERTYPE.Reply => 200, MyCommon.WORKERTYPE.UserTimeline => 200, MyCommon.WORKERTYPE.Favorites => 200, From db7fcd821ae27c4494bd1f5404507d9bc84a0a9a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 16:17:30 +0900 Subject: [PATCH 208/402] =?UTF-8?q?=E3=80=8C=E3=83=97=E3=83=AD=E3=83=95?= =?UTF-8?q?=E3=82=A3=E3=83=BC=E3=83=AB=E8=A1=A8=E7=A4=BA=E3=80=8D=E3=80=8C?= =?UTF-8?q?=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=AE=E3=82=BF=E3=82=A4?= =?UTF-8?q?=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3=E3=82=92=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E3=80=8D=E3=81=AE=E3=83=A1=E3=83=8B=E3=83=A5=E3=83=BC=E9=A0=85?= =?UTF-8?q?=E7=9B=AE=E3=82=92=E5=86=8D=E5=BA=A6=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Tween.Designer.cs | 36 ++++++++++++++++++++++++++++++++++++ OpenTween/Tween.en.resx | 8 ++++++++ OpenTween/Tween.resx | 16 ++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/OpenTween/Tween.Designer.cs b/OpenTween/Tween.Designer.cs index b1aae02e1..1d002462e 100644 --- a/OpenTween/Tween.Designer.cs +++ b/OpenTween/Tween.Designer.cs @@ -104,7 +104,9 @@ private void InitializeComponent() this.FavoriteRetweetUnofficialMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.UnFavOpMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripSeparator38 = new System.Windows.Forms.ToolStripSeparator(); + this.ShowProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShowRelatedStatusesMenuItem2 = new System.Windows.Forms.ToolStripMenuItem(); + this.ShowUserTimelineMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorShowProfileMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorShowUserTimelineMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -241,7 +243,9 @@ private void InitializeComponent() this.FavoriteRetweetUnofficialContextMenu = new System.Windows.Forms.ToolStripMenuItem(); this.FavRemoveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ToolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator(); + this.ShowProfileContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ShowRelatedStatusesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.ShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorShowProfileContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.AuthorShowUserTimelineContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -919,7 +923,9 @@ private void InitializeComponent() this.FavoriteRetweetUnofficialMenuItem, this.UnFavOpMenuItem, this.ToolStripSeparator38, + this.ShowProfileMenuItem, this.ShowRelatedStatusesMenuItem2, + this.ShowUserTimelineMenuItem, this.AuthorMenuItem, this.RetweetedByMenuItem, this.OpenOpMenuItem, @@ -1006,12 +1012,24 @@ private void InitializeComponent() this.ToolStripSeparator38.Name = "ToolStripSeparator38"; resources.ApplyResources(this.ToolStripSeparator38, "ToolStripSeparator38"); // + // ShowProfileMenuItem + // + this.ShowProfileMenuItem.Name = "ShowProfileMenuItem"; + resources.ApplyResources(this.ShowProfileMenuItem, "ShowProfileMenuItem"); + this.ShowProfileMenuItem.Click += new System.EventHandler(this.AuthorShowProfileMenuItem_Click); + // // ShowRelatedStatusesMenuItem2 // this.ShowRelatedStatusesMenuItem2.Name = "ShowRelatedStatusesMenuItem2"; resources.ApplyResources(this.ShowRelatedStatusesMenuItem2, "ShowRelatedStatusesMenuItem2"); this.ShowRelatedStatusesMenuItem2.Click += new System.EventHandler(this.ShowRelatedStatusesMenuItem_Click); // + // ShowUserTimelineMenuItem + // + this.ShowUserTimelineMenuItem.Name = "ShowUserTimelineMenuItem"; + resources.ApplyResources(this.ShowUserTimelineMenuItem, "ShowUserTimelineMenuItem"); + this.ShowUserTimelineMenuItem.Click += new System.EventHandler(this.AuthorShowUserTimelineMenuItem_Click); + // // AuthorMenuItem // this.AuthorMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -1857,7 +1875,9 @@ private void InitializeComponent() this.FavoriteRetweetUnofficialContextMenu, this.FavRemoveToolStripMenuItem, this.ToolStripSeparator2, + this.ShowProfileContextMenuItem, this.ShowRelatedStatusesMenuItem, + this.ShowUserTimelineContextMenuItem, this.AuthorContextMenuItem, this.RetweetedByContextMenuItem, this.ToolStripMenuItem6, @@ -1945,12 +1965,24 @@ private void InitializeComponent() this.ToolStripSeparator2.Name = "ToolStripSeparator2"; resources.ApplyResources(this.ToolStripSeparator2, "ToolStripSeparator2"); // + // ShowProfileContextMenuItem + // + this.ShowProfileContextMenuItem.Name = "ShowProfileContextMenuItem"; + resources.ApplyResources(this.ShowProfileContextMenuItem, "ShowProfileContextMenuItem"); + this.ShowProfileContextMenuItem.Click += new System.EventHandler(this.AuthorShowProfileMenuItem_Click); + // // ShowRelatedStatusesMenuItem // this.ShowRelatedStatusesMenuItem.Name = "ShowRelatedStatusesMenuItem"; resources.ApplyResources(this.ShowRelatedStatusesMenuItem, "ShowRelatedStatusesMenuItem"); this.ShowRelatedStatusesMenuItem.Click += new System.EventHandler(this.ShowRelatedStatusesMenuItem_Click); // + // ShowUserTimelineContextMenuItem + // + this.ShowUserTimelineContextMenuItem.Name = "ShowUserTimelineContextMenuItem"; + resources.ApplyResources(this.ShowUserTimelineContextMenuItem, "ShowUserTimelineContextMenuItem"); + this.ShowUserTimelineContextMenuItem.Click += new System.EventHandler(this.AuthorShowUserTimelineMenuItem_Click); + // // AuthorContextMenuItem // this.AuthorContextMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -2397,5 +2429,9 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem RetweetedByShowUserTimelineContextMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByListManageContextMenuItem; private System.Windows.Forms.ToolStripMenuItem RetweetedByOpenInBrowserContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem ShowProfileMenuItem; + private System.Windows.Forms.ToolStripMenuItem ShowUserTimelineMenuItem; + private System.Windows.Forms.ToolStripMenuItem ShowProfileContextMenuItem; + private System.Windows.Forms.ToolStripMenuItem ShowUserTimelineContextMenuItem; } } \ No newline at end of file diff --git a/OpenTween/Tween.en.resx b/OpenTween/Tween.en.resx index dc4c7ccd4..98bab48e0 100644 --- a/OpenTween/Tween.en.resx +++ b/OpenTween/Tween.en.resx @@ -427,10 +427,18 @@ Settings (&O)... 278, 24 Shortcut keys + 199, 22 + User &Profile + 259, 22 + User &Profile 258, 24 Related Posts (&G) 347, 24 Related Posts (&G) + 199, 22 + User's updates + 259, 22 + User's updates Select a wav file. 122, 22 &Source diff --git a/OpenTween/Tween.resx b/OpenTween/Tween.resx index 2bfdb2387..320f436d1 100644 --- a/OpenTween/Tween.resx +++ b/OpenTween/Tween.resx @@ -344,10 +344,18 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShortcutKeyListMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowProfileContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowProfileMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShowRelatedStatusesMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ShowRelatedStatusesMenuItem2 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowUserTimelineContextMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ShowUserTimelineMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 SoundFileComboBox System.Windows.Forms.ToolStripComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 SoundFileTbComboBox @@ -963,10 +971,18 @@ 設定(&O)... 251, 22 ショートカットキー一覧 + 223, 22 + プロフィール表示 + 243, 22 + プロフィール表示 241, 22 関連発言表示(&G) 313, 22 関連発言表示(&G) + 223, 22 + ユーザーのタイムラインを表示 + 243, 22 + ユーザーのタイムラインを表示 121, 23 再生するwavファイルを指定してください 121, 23 From 66543fa40add0e7adc7549767d9ef4c59d2627e6 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 17:04:03 +0900 Subject: [PATCH 209/402] =?UTF-8?q?Twemoji=E3=81=AE=E6=AD=A3=E8=A6=8F?= =?UTF-8?q?=E8=A1=A8=E7=8F=BE=E3=83=91=E3=82=BF=E3=83=BC=E3=83=B3=E3=82=92?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/twitter/twemoji-parser/blob/v14.0.0/src/lib/regex.js#L5 --- OpenTween.Tests/TweetExtractorTest.cs | 12 ++++++++++++ OpenTween/Resources/ChangeLog.txt | 2 ++ OpenTween/TweetExtractor.cs | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/OpenTween.Tests/TweetExtractorTest.cs b/OpenTween.Tests/TweetExtractorTest.cs index 1c03a8e91..942440d46 100644 --- a/OpenTween.Tests/TweetExtractorTest.cs +++ b/OpenTween.Tests/TweetExtractorTest.cs @@ -304,6 +304,18 @@ public void ExtractEmojiEntities_Unicode13Test() Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f977.png", entity.Url); } + [Fact] + public void ExtractEmojiEntities_Unicode14Test() + { + // Unicode 14.0 で追加された絵文字 + var origText = "🫠"; // U+1FAE0 (MELTING FACE) + var entity = TweetExtractor.ExtractEmojiEntities(origText).Single(); + + Assert.Equal(new[] { 0, 1 }, entity.Indices); + Assert.Equal("🫠", entity.Text); + Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1fae0.png", entity.Url); + } + [Fact] public void ExtractEmojiEntities_EmojiModifiers_CombiningTest() { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 820bc5ac7..38c043be7 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -11,6 +11,8 @@ - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります * NEW: 発言のダブルクリック時の動作に「Reply All」(@返信ALL)を追加 * NEW: 関連発言表示で会話ツリーの最新の発言を取得する機能を追加 + * NEW: Twemoji 14.0 に対応しました + - Unicode 14.0 で追加された絵文字が表示されるようになります * CHG: ツイートの投稿者とRTしたユーザーに関するメニュー項目を整理 * CHG: DMが選択されている時は「@返信」「@返信ALL」のどちらも「DM送信」と同じ動作となるように変更 * CHG: 複数のユーザー宛のリプライ時にツイートの先頭にピリオドを加える仕様を廃止 diff --git a/OpenTween/TweetExtractor.cs b/OpenTween/TweetExtractor.cs index 62cae27cc..da822153d 100644 --- a/OpenTween/TweetExtractor.cs +++ b/OpenTween/TweetExtractor.cs @@ -34,7 +34,7 @@ namespace OpenTween { public static class TweetExtractor { - public static readonly Regex EmojiPattern = new(@"(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f"); + public static readonly Regex EmojiPattern = new(@"(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83e\udef1\ud83c\udffb\u200d\ud83e\udef2\ud83c[\udffc-\udfff]|\ud83e\udef1\ud83c\udffc\u200d\ud83e\udef2\ud83c[\udffb\udffd-\udfff]|\ud83e\udef1\ud83c\udffd\u200d\ud83e\udef2\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\udef1\ud83c\udffe\u200d\ud83e\udef2\ud83c[\udffb-\udffd\udfff]|\ud83e\udef1\ud83c\udfff\u200d\ud83e\udef2\ud83c[\udffb-\udffe]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83e\udd1d\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91]|\ud83e\udd1d)|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd\udec3-\udec5\udef0-\udef6]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udedd-\udedf\udeeb\udeec\udef4-\udefc\udfe0-\udfeb\udff0]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78-\uddb4\uddb7\uddba\uddbc-\uddcc\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7c\ude80-\ude86\ude90-\udeac\udeb0-\udeba\udec0-\udec2\uded0-\uded9\udee0-\udee7]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f"); /// /// テキストから URL を抽出して返します From cbb4c1fb216433a0b0ba136b030c9b1cb4a200bd Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 19:57:59 +0900 Subject: [PATCH 210/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E3=82=A2=E3=82=A4=E3=82=B3=E3=83=B3=E7=94=BB=E5=83=8F?= =?UTF-8?q?=E5=8F=96=E5=BE=97=E6=99=82=E3=81=AB=E7=99=BA=E7=94=9F=E3=81=97?= =?UTF-8?q?=E3=81=9F=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=8C=E9=81=A9=E5=88=87?= =?UTF-8?q?=E3=81=AB=E5=87=A6=E7=90=86=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84?= =?UTF-8?q?=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3=20(thx?= =?UTF-8?q?=20@mulsys!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://osdn.net/projects/opentween/ticket/45203 Fixes: 92f0a891 ("ImageListViewItemを削除し通常のListViewItemのみを使用する") --- OpenTween/TimelineListViewDrawer.cs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs index 252b35583..8a58d600a 100644 --- a/OpenTween/TimelineListViewDrawer.cs +++ b/OpenTween/TimelineListViewDrawer.cs @@ -28,6 +28,7 @@ using System; using System.Drawing; +using System.Net.Http; using System.Threading.Tasks; using System.Windows.Forms; using OpenTween.Models; @@ -183,8 +184,23 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) // キャッシュにない画像の場合は読み込みが完了してから再描画する _ = Task.Run(async () => { - var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); - var image = await this.iconCache.DownloadImageAsync(imageUrl); + try + { + var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); + await this.iconCache.DownloadImageAsync(imageUrl); + } + catch (InvalidImageException) + { + return; + } + catch (HttpRequestException) + { + return; + } + catch (OperationCanceledException) + { + return; + } await this.listView.InvokeAsync(() => { From 9d69549373b5df8c322e3eb11f0a417047cfaf35 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 20:17:03 +0900 Subject: [PATCH 211/402] =?UTF-8?q?=E3=80=8C=E3=83=84=E3=82=A4=E3=83=BC?= =?UTF-8?q?=E3=83=88URL=E3=82=92=E9=96=8B=E3=81=8F=E3=80=8D=E3=81=A7Overfl?= =?UTF-8?q?owException=E3=81=8C=E7=99=BA=E7=94=9F=E3=81=99=E3=82=8B?= =?UTF-8?q?=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://osdn.net/projects/opentween/ticket/45204 Fixes: 7f2fa759 ("ファイルメニューに「ツイートURLを開く」を追加") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 22 ++++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 38c043be7..ba2b47767 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -26,6 +26,7 @@ * FIX: 自分のツイートに対する「@返信ALL」で自分宛のMentionが付かない不具合を修正 (thx @doug_lee42!) * FIX: 関連発言表示によって内部の未読状態と未読表示が一致しない状態になる不具合を修正 (thx @wal_san!) * FIX: Webブラウザ起動時にエラーが発生した場合に正しくエラーメッセージが表示されない不具合を修正 + * FIX: 「ツイートURLを開く」で極端に大きなIDが入力された場合に正しくエラーメッセージが表示されない不具合を修正 ==== Ver 2.5.0(2022/02/05) * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 02bc23a78..923287d3d 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -5799,6 +5799,17 @@ private void SaveConfigsTabs() private async void OpenURLFileMenuItem_Click(object sender, EventArgs e) { + static void ShowFormatErrorDialog(IWin32Window owner) + { + MessageBox.Show( + owner, + Properties.Resources.OpenURL_InvalidFormat, + Properties.Resources.OpenURL_Caption, + MessageBoxButtons.OK, + MessageBoxIcon.Error + ); + } + var ret = InputDialog.Show(this, Properties.Resources.OpenURL_InputText, Properties.Resources.OpenURL_Caption, out var inputText); if (ret != DialogResult.OK) return; @@ -5806,12 +5817,7 @@ private async void OpenURLFileMenuItem_Click(object sender, EventArgs e) var match = Twitter.StatusUrlRegex.Match(inputText); if (!match.Success) { - MessageBox.Show( - this, - Properties.Resources.OpenURL_InvalidFormat, - Properties.Resources.OpenURL_Caption, - MessageBoxButtons.OK, - MessageBoxIcon.Error); + ShowFormatErrorDialog(this); return; } @@ -5820,6 +5826,10 @@ private async void OpenURLFileMenuItem_Click(object sender, EventArgs e) var statusId = long.Parse(match.Groups["StatusId"].Value); await this.OpenRelatedTab(statusId); } + catch (OverflowException) + { + ShowFormatErrorDialog(this); + } catch (TabException ex) { MessageBox.Show(this, ex.Message, ApplicationSettings.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error); From 6f2696dc856f9f7a57c5e7d11833fd9f8d35318f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 22:03:47 +0900 Subject: [PATCH 212/402] =?UTF-8?q?OpenTween=20v2.6.0=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 25 ++++++++++------------ OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 4d9dec078..66febacc1 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.5.0.1")] +[assembly: AssemblyVersion("2.6.0.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index a282f0ad6..ad28e3415 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,20 +571,17 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Ver 2.5.1-dev(2022/xx/xx) - /// - ///==== Ver 2.5.0(2022/02/05) - /// * NEW: アカウント追加時の認可URLを右クリックでコピー可能にしました - /// * NEW: Twemoji 13.1 に対応しました - /// - Unicode 13.0 で追加された絵文字が表示されるようになります - /// * CHG: pic.twitter.com の画像URLのフォーマット変更に対応 - /// * CHG: Instagramのサムネイルを表示するURLのパターンを追加 - /// * CHG: YouTubeのサムネイルを表示するURLのパターンを追加 (thx @Hawklaver!) - /// * CHG: UserStreams関係の機能を削除 - /// * CHG: 設定画面にある通知関係の項目の配置を移動 - /// * CHG: タブ別の新着通知表示のデフォルト設定を変更 - /// * Reply, DM タブ以外は新着通知表示がデフォルトでオフになります(従来はタブの種別に関わらずデフォルトでオン) - /// * CHG: 「Listの発言取得に公式RTを含める」のデフォル [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + ///==== Ver 2.6.0(2022/07/24) + /// * NEW: Recentタブの発言の取得に Twitter API v2 を使用 + /// - 従来の API v1.1 と比べて、15分間に取得できる回数の制限が15→180回に緩和、一度に取得できる件数が200→100件になります + /// * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) + /// * NEW: 発言詳細欄の名前やアイコンのクリックによるプロフィール表示に対応 + /// * NEW: クリップボード経由での複数枚の画像ファイル添付に対応 + /// * NEW: 画面上に表示する解像度に応じたプロフィール画像の取得に対応 + /// - 高DPI環境で表示した場合により高解像度のプロフィール画像が取得されるようになります + /// - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります + /// * NEW: 発言のダブルクリック時の動作に「Reply All」(@返信ALL)を追加 + /// * NEW: 関連発言表 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index ba2b47767..31a6d29c8 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Ver 2.5.1-dev(2022/xx/xx) +==== Ver 2.6.0(2022/07/24) * NEW: Recentタブの発言の取得に Twitter API v2 を使用 - 従来の API v1.1 と比べて、15分間に取得できる回数の制限が15→180回に緩和、一度に取得できる件数が200→100件になります * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) From cd1c5c8c0370e915558e883382791db6fe6e9fdf Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 22:14:00 +0900 Subject: [PATCH 213/402] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.6.1-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 5 +++-- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 66febacc1..c988e93f5 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.6.0.0")] +[assembly: AssemblyVersion("2.6.0.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index ad28e3415..3a7f625bf 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,6 +571,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Unreleased + /// ///==== Ver 2.6.0(2022/07/24) /// * NEW: Recentタブの発言の取得に Twitter API v2 を使用 /// - 従来の API v1.1 と比べて、15分間に取得できる回数の制限が15→180回に緩和、一度に取得できる件数が200→100件になります @@ -580,8 +582,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * NEW: 画面上に表示する解像度に応じたプロフィール画像の取得に対応 /// - 高DPI環境で表示した場合により高解像度のプロフィール画像が取得されるようになります /// - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります - /// * NEW: 発言のダブルクリック時の動作に「Reply All」(@返信ALL)を追加 - /// * NEW: 関連発言表 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * NEW: 発言のダブルクリック時の動作に「Reply All」(@返信ALL [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 31a6d29c8..3bf782e94 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Unreleased + ==== Ver 2.6.0(2022/07/24) * NEW: Recentタブの発言の取得に Twitter API v2 を使用 - 従来の API v1.1 と比べて、15分間に取得できる回数の制限が15→180回に緩和、一度に取得できる件数が200→100件になります diff --git a/appveyor.yml b/appveyor.yml index 43838a454..625bbe047 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.5.0.{build} +version: 2.6.0.{build} os: Visual Studio 2022 From fd970feb9696a68cf8c73e2c0c947f8041c740bd Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 22:48:01 +0900 Subject: [PATCH 214/402] =?UTF-8?q?=E3=83=AA=E3=83=AA=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=82=B0=E3=82=92Appveyor=E3=81=AE=E3=83=93=E3=83=AB?= =?UTF-8?q?=E3=83=89=E5=AF=BE=E8=B1=A1=E3=81=AB=E5=90=AB=E3=82=81=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 625bbe047..cc7045466 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,6 +22,7 @@ branches: only: - develop - release + - /^OpenTween.+/ # release tag for: - # for dev build From bf4f0577bfff858e10e5709fae41be2603ae92b9 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 22:48:01 +0900 Subject: [PATCH 215/402] =?UTF-8?q?=E3=83=AA=E3=83=AA=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=82=BF=E3=82=B0=E3=82=92Appveyor=E3=81=AE=E3=83=93=E3=83=AB?= =?UTF-8?q?=E3=83=89=E5=AF=BE=E8=B1=A1=E3=81=AB=E5=90=AB=E3=82=81=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit fd970feb9696a68cf8c73e2c0c947f8041c740bd) --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 43838a454..3e8c4e0eb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -22,6 +22,7 @@ branches: only: - develop - release + - /^OpenTween.+/ # release tag for: - # for dev build From b9a24f318b2a0537f259e5906b5b8f4ef3105d98 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 22:56:22 +0900 Subject: [PATCH 216/402] =?UTF-8?q?appveyor.yml=E3=81=A7Release=E3=83=93?= =?UTF-8?q?=E3=83=AB=E3=83=89=E3=81=8C=E8=80=83=E6=85=AE=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=AA=E3=81=84=E7=AE=87=E6=89=80=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index cc7045466..1470b19c1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -66,7 +66,7 @@ test_script: set targetFramework=net472 set nugetPackages=%UserProfile%\.nuget\packages - %nugetPackages%\altcover\%altCoverVersion%\tools\%targetFramework%\AltCover.exe --inputDirectory .\OpenTween.Tests\bin\Debug\%targetFramework%\ --outputDirectory .\__Instrumented\ --assemblyFilter "?^OpenTween(?!\.Tests)" --typeFilter "?^OpenTween\." --fileFilter "\.Designer\.cs" --visibleBranches + %nugetPackages%\altcover\%altCoverVersion%\tools\%targetFramework%\AltCover.exe --inputDirectory .\OpenTween.Tests\bin\%CONFIGURATION%\%targetFramework%\ --outputDirectory .\__Instrumented\ --assemblyFilter "?^OpenTween(?!\.Tests)" --typeFilter "?^OpenTween\." --fileFilter "\.Designer\.cs" --visibleBranches %nugetPackages%\altcover\%altCoverVersion%\tools\%targetFramework%\AltCover.exe runner --recorderDirectory .\__Instrumented\ --executable %nugetPackages%\xunit.runner.console\%xunitVersion%\tools\%targetFramework%\xunit.console.exe -- .\__Instrumented\OpenTween.Tests.dll From 105812d45322dbcb0327dd3ff64db41adb46b30b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 24 Jul 2022 22:56:22 +0900 Subject: [PATCH 217/402] =?UTF-8?q?appveyor.yml=E3=81=A7Release=E3=83=93?= =?UTF-8?q?=E3=83=AB=E3=83=89=E3=81=8C=E8=80=83=E6=85=AE=E3=81=97=E3=81=A6?= =?UTF-8?q?=E3=81=84=E3=81=AA=E3=81=84=E7=AE=87=E6=89=80=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit b9a24f318b2a0537f259e5906b5b8f4ef3105d98) --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 3e8c4e0eb..69da5f3fb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -66,7 +66,7 @@ test_script: set targetFramework=net472 set nugetPackages=%UserProfile%\.nuget\packages - %nugetPackages%\altcover\%altCoverVersion%\tools\%targetFramework%\AltCover.exe --inputDirectory .\OpenTween.Tests\bin\Debug\%targetFramework%\ --outputDirectory .\__Instrumented\ --assemblyFilter "?^OpenTween(?!\.Tests)" --typeFilter "?^OpenTween\." --fileFilter "\.Designer\.cs" --visibleBranches + %nugetPackages%\altcover\%altCoverVersion%\tools\%targetFramework%\AltCover.exe --inputDirectory .\OpenTween.Tests\bin\%CONFIGURATION%\%targetFramework%\ --outputDirectory .\__Instrumented\ --assemblyFilter "?^OpenTween(?!\.Tests)" --typeFilter "?^OpenTween\." --fileFilter "\.Designer\.cs" --visibleBranches %nugetPackages%\altcover\%altCoverVersion%\tools\%targetFramework%\AltCover.exe runner --recorderDirectory .\__Instrumented\ --executable %nugetPackages%\xunit.runner.console\%xunitVersion%\tools\%targetFramework%\xunit.console.exe -- .\__Instrumented\OpenTween.Tests.dll From 3f222ff5999c05681f1756654f447d404ebd6ac7 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 29 Jul 2022 03:01:19 +0900 Subject: [PATCH 218/402] =?UTF-8?q?=E3=82=BF=E3=83=96=E3=81=AE=E7=A7=BB?= =?UTF-8?q?=E5=8B=95=E5=BE=8C=E3=81=AB=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=8C=E7=A9=BA=E3=81=AE=E8=A1=A8=E7=A4=BA=E3=81=AB=E3=81=AA?= =?UTF-8?q?=E3=82=8B=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: d5d2f848 ("発言一覧のVirtualModeに関する実装をTimelineListViewCacheクラスに分離") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 3bf782e94..e80b735f3 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Unreleased + * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 ==== Ver 2.6.0(2022/07/24) * NEW: Recentタブの発言の取得に Twitter API v2 を使用 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 923287d3d..02a60382f 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -6038,6 +6038,11 @@ public void ReOrderTab(string targetTabText, string baseTabText, bool isBeforeBa using (ControlTransaction.Layout(this.ListTab)) { + // 選択中のタブを Remove メソッドで取り外すと選択状態が変化して Selecting イベントが発生するが、 + // この時 TabInformations と TabControl の並び順が不一致なままで ListTabSelect メソッドが呼ばれてしまう。 + // これを防ぐために、Remove メソッドを呼ぶ前に選択中のタブを切り替えておく必要がある + this.ListTab.SelectedIndex = targetIndex == 0 ? 1 : 0; + var tab = this.statuses.Tabs[targetIndex]; var tabPage = this.ListTab.TabPages[targetIndex]; From 40816369ff26074aae69a05fcaa44876ecf0089a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 01:36:32 +0900 Subject: [PATCH 219/402] =?UTF-8?q?Revert=20"InvokeAsync=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=82=92OTBaseForm=E3=81=8B=E3=82=89Extensio?= =?UTF-8?q?ns=E3=81=AB=E7=A7=BB=E5=8B=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://osdn.net/projects/opentween/ticket/45270 に対する修正 This reverts commit d9a31c03eed831b41300200e766d5fb531badf3a. --- OpenTween.Tests/OTBaseFormTest.cs | 59 +++++++++++++++++++++++++++++++ OpenTween/Extensions.cs | 37 ------------------- OpenTween/OTBaseForm.cs | 41 +++++++++++++++++++++ 3 files changed, 100 insertions(+), 37 deletions(-) diff --git a/OpenTween.Tests/OTBaseFormTest.cs b/OpenTween.Tests/OTBaseFormTest.cs index d8ded2720..e89f26148 100644 --- a/OpenTween.Tests/OTBaseFormTest.cs +++ b/OpenTween.Tests/OTBaseFormTest.cs @@ -42,6 +42,65 @@ public OTBaseFormTest() protected void SetupSynchronizationContext() => WindowsFormsSynchronizationContext.AutoInstall = false; + [Fact] + public async Task InvokeAsync_Test() + { + using var form = new TestForm(); + await Task.Run(async () => + { + await form.InvokeAsync(() => form.Text = "hoge"); + }); + + Assert.Equal("hoge", form.Text); + } + + [Fact] + public async Task InvokeAsync_ReturnValueTest() + { + using var form = new TestForm(); + form.Text = "hoge"; + + await Task.Run(async () => + { + var ret = await form.InvokeAsync(() => form.Text); + Assert.Equal("hoge", ret); + }); + } + + [Fact] + public async Task InvokeAsync_TaskTest() + { + using var form = new TestForm(); + await Task.Run(async () => + { + await form.InvokeAsync(async () => + { + await Task.Delay(1); + form.Text = "hoge"; + }); + }); + + Assert.Equal("hoge", form.Text); + } + + [Fact] + public async Task InvokeAsync_TaskWithValueTest() + { + using var form = new TestForm(); + form.Text = "hoge"; + + await Task.Run(async () => + { + var ret = await form.InvokeAsync(async () => + { + await Task.Delay(1); + return form.Text; + }); + + Assert.Equal("hoge", ret); + }); + } + [Fact] public void ScaleChildControl_ListViewTest() { diff --git a/OpenTween/Extensions.cs b/OpenTween/Extensions.cs index 294a9e03e..788fed1e8 100644 --- a/OpenTween/Extensions.cs +++ b/OpenTween/Extensions.cs @@ -46,43 +46,6 @@ public static string GetSelectedText(this WebBrowser webBrowser) return selectedText; } - public static Task InvokeAsync(this Control control, Action x) - { - return control.InvokeAsync(new Func(() => - { - x(); - return 0; - })); - } - - public static Task InvokeAsync(this Control control, Func x) - => control.InvokeAsync(x).Unwrap(); - - public static Task InvokeAsync(this Control control, Func> x) - => control.InvokeAsync>(x).Unwrap(); - - /// - /// メソッドのTask版みたいなやつ - /// - public static Task InvokeAsync(this Control control, Func x) - { - var tcs = new TaskCompletionSource(); - control.BeginInvoke(() => - { - try - { - var ret = x(); - tcs.SetResult(ret); - } - catch (Exception ex) - { - tcs.SetException(ex); - } - }); - - return tcs.Task; - } - public static ReadLockTransaction BeginReadTransaction(this ReaderWriterLockSlim lockObj) => new(lockObj); diff --git a/OpenTween/OTBaseForm.cs b/OpenTween/OTBaseForm.cs index 982057193..8a0c58882 100644 --- a/OpenTween/OTBaseForm.cs +++ b/OpenTween/OTBaseForm.cs @@ -54,9 +54,12 @@ public class OTBaseForm : Form /// public SizeF CurrentScaleFactor { get; private set; } + private readonly SynchronizationContext synchronizationContext; + protected OTBaseForm() { this.CurrentScaleFactor = new SizeF(1.0f, 1.0f); + this.synchronizationContext = SynchronizationContext.Current; this.Load += (o, e) => { @@ -66,6 +69,44 @@ protected OTBaseForm() }; } + public Task InvokeAsync(Action x) + { + return this.InvokeAsync(new Func(() => + { + x(); + return 0; + })); + } + + public Task InvokeAsync(Func x) + => this.InvokeAsync(x).Unwrap(); + + public Task InvokeAsync(Func> x) + => this.InvokeAsync>(x).Unwrap(); + + /// + /// メソッドのTask版みたいなやつ + /// + public Task InvokeAsync(Func x) + { + var tcs = new TaskCompletionSource(); + this.synchronizationContext.Post(_ => + { + try + { + var ret = x(); + tcs.SetResult(ret); + } + catch (Exception ex) + { + tcs.SetException(ex); + } + }, + null); + + return tcs.Task; + } + /// /// source で指定されたフォントのスタイルを維持しつつ GlobalFont に置き換えた Font を返します /// From c0d84689b35849470420281bb2484b527aff20d3 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 01:43:04 +0900 Subject: [PATCH 220/402] =?UTF-8?q?ListView=E3=81=AB=E5=AF=BE=E3=81=97?= =?UTF-8?q?=E3=81=A6InvokeAsync=E3=81=99=E3=82=8B=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AFOTBaseForm=E3=82=92=E7=B5=8C=E7=94=B1=E3=81=95?= =?UTF-8?q?=E3=81=9B=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 37a94f89 で InvokeAsync メソッドを Extensions から OTBaseForm に戻したことによる修正 --- OpenTween/TimelineListViewDrawer.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs index 8a58d600a..1e2ae355f 100644 --- a/OpenTween/TimelineListViewDrawer.cs +++ b/OpenTween/TimelineListViewDrawer.cs @@ -69,6 +69,7 @@ private int IconSizeNumeric }; private readonly DetailsListView listView; + private readonly OTBaseForm parentForm; private readonly TabModel tab; private readonly TimelineListViewCache listViewCache; private readonly ImageCache iconCache; @@ -84,6 +85,7 @@ ThemeManager theme ) { this.listView = listView; + this.parentForm = (OTBaseForm)listView.FindForm(); this.tab = tab; this.listViewCache = listViewCache; this.iconCache = iconCache; @@ -202,7 +204,7 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) return; } - await this.listView.InvokeAsync(() => + await this.parentForm.InvokeAsync(() => { if (this.listView.IsDisposed) return; From 47bb8b3a30dc54d35aec9398381dd007faf6eaad Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 01:47:51 +0900 Subject: [PATCH 221/402] =?UTF-8?q?ChangeLog=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 40816369ff26074aae69a05fcaa44876ecf0089a での変更を反映 --- OpenTween/Resources/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index e80b735f3..e61c58f28 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Unreleased * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 + * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 ==== Ver 2.6.0(2022/07/24) * NEW: Recentタブの発言の取得に Twitter API v2 を使用 From e3a9b4d572c422b256c3de628b2d242ceefc4b77 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 03:39:49 +0900 Subject: [PATCH 222/402] =?UTF-8?q?=E3=83=9B=E3=83=BC=E3=83=A0=E3=82=BF?= =?UTF-8?q?=E3=82=A4=E3=83=A0=E3=83=A9=E3=82=A4=E3=83=B3=E3=81=AE=E8=AA=AD?= =?UTF-8?q?=E8=BE=BC=E6=99=82=E3=81=AB=20data=20=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E3=83=89=E3=81=8C=20null=20=E3=81=AB?= =?UTF-8?q?=E3=81=AA=E3=81=A3=E3=81=A6=E3=81=84=E3=81=9F=E5=A0=B4=E5=90=88?= =?UTF-8?q?=E3=81=AF=E7=84=A1=E8=A6=96=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://osdn.net/projects/opentween/ticket/45234 Fixes: e03de8b0 ("Recentタブのツイート取得にTwitter API v2を使用する") --- OpenTween/Api/DataModel/TwitterV2TweetIds.cs | 2 +- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Twitter.cs | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenTween/Api/DataModel/TwitterV2TweetIds.cs b/OpenTween/Api/DataModel/TwitterV2TweetIds.cs index 6b61b9c4d..61ad9aa7e 100644 --- a/OpenTween/Api/DataModel/TwitterV2TweetIds.cs +++ b/OpenTween/Api/DataModel/TwitterV2TweetIds.cs @@ -29,6 +29,6 @@ namespace OpenTween.Api.DataModel public class TwitterV2TweetIds { [DataMember(Name = "data")] - public TwitterV2TweetId[] Data { get; set; } + public TwitterV2TweetId[]? Data { get; set; } } } diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index e61c58f28..aa4e2911f 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -3,6 +3,7 @@ ==== Unreleased * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 + * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 ==== Ver 2.6.0(2022/07/24) * NEW: Recentタブの発言の取得に Twitter API v2 を使用 diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 1eab17e64..87ce8ec8c 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -519,6 +519,9 @@ public async Task GetHomeTimelineApi(bool read, HomeTabModel tab, bool more, boo var response = await request.Send(this.Api.Connection) .ConfigureAwait(false); + if (response.Data == null || response.Data.Length == 0) + return; + var tweetIds = response.Data.Select(x => x.Id).ToList(); var statuses = await this.Api.StatusesLookup(tweetIds) From 5b895e5befe417cc07da466b0f667e9ee5504e5d Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 05:14:18 +0900 Subject: [PATCH 223/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E8=A9=B3=E7=B4=B0?= =?UTF-8?q?=E9=83=A8=E3=81=AE=E6=8A=95=E7=A8=BF=E6=97=A5=E6=99=82=E3=83=A9?= =?UTF-8?q?=E3=83=99=E3=83=AB=E3=82=92=E3=82=AF=E3=83=AA=E3=83=83=E3=82=AF?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/TweetDetailsView.Designer.cs | 9 +++++++-- OpenTween/TweetDetailsView.cs | 9 +++++++++ OpenTween/TweetDetailsView.resx | 3 +-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index aa4e2911f..59b8e6f32 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Unreleased + * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 diff --git a/OpenTween/TweetDetailsView.Designer.cs b/OpenTween/TweetDetailsView.Designer.cs index a4c6843e4..9c6dc0e3e 100644 --- a/OpenTween/TweetDetailsView.Designer.cs +++ b/OpenTween/TweetDetailsView.Designer.cs @@ -75,7 +75,7 @@ private void InitializeComponent() this.UseHashtagMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.SelectionTranslationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.TranslationToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.DateTimeLabel = new System.Windows.Forms.Label(); + this.DateTimeLabel = new System.Windows.Forms.LinkLabel(); this.SourceLinkLabel = new System.Windows.Forms.LinkLabel(); this.ContextMenuSource = new System.Windows.Forms.ContextMenuStrip(this.components); this.SourceCopyMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -422,9 +422,14 @@ private void InitializeComponent() // // DateTimeLabel // + this.DateTimeLabel.ActiveLinkColor = System.Drawing.SystemColors.ControlText; resources.ApplyResources(this.DateTimeLabel, "DateTimeLabel"); this.DateTimeLabel.AutoEllipsis = true; + this.DateTimeLabel.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline; + this.DateTimeLabel.LinkColor = System.Drawing.SystemColors.ControlText; this.DateTimeLabel.Name = "DateTimeLabel"; + this.DateTimeLabel.TabStop = true; + this.DateTimeLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.DateTimeLabel_LinkClicked); // // SourceLinkLabel // @@ -485,7 +490,6 @@ private void InitializeComponent() private System.Windows.Forms.LinkLabel AuthorNameLinkLabel; private System.Windows.Forms.LinkLabel RetweetedByLinkLabel; internal System.Windows.Forms.WebBrowser PostBrowser; - internal System.Windows.Forms.Label DateTimeLabel; internal System.Windows.Forms.LinkLabel SourceLinkLabel; internal System.Windows.Forms.ContextMenuStrip ContextMenuPostBrowser; internal System.Windows.Forms.ToolStripMenuItem SelectionSearchContextMenuItem; @@ -529,5 +533,6 @@ private void InitializeComponent() internal System.Windows.Forms.ContextMenuStrip ContextMenuSource; internal System.Windows.Forms.ToolStripMenuItem SourceCopyMenuItem; internal System.Windows.Forms.ToolStripMenuItem SourceUrlCopyMenuItem; + private System.Windows.Forms.LinkLabel DateTimeLabel; } } diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 4f8a5350f..5151f44ac 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -1124,6 +1124,15 @@ private async void RetweetedByLinkLabel_LinkClicked(object sender, LinkLabelLink if (screenName != null) await this.Owner.ShowUserStatus(screenName, showInputDialog: false); } + + private async void DateTimeLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + if (this.CurrentPost == null) + return; + + var statusUrl = MyCommon.GetStatusUrl(this.CurrentPost); + await MyCommon.OpenInBrowserAsync(this, statusUrl); + } } public class TweetDetailsViewStatusChengedEventArgs : EventArgs diff --git a/OpenTween/TweetDetailsView.resx b/OpenTween/TweetDetailsView.resx index f7c950d4e..f6a907642 100644 --- a/OpenTween/TweetDetailsView.resx +++ b/OpenTween/TweetDetailsView.resx @@ -26,7 +26,7 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 DateTimeLabel TableLayoutPanel1 - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 3 flowLayoutPanel1 TableLayoutPanel1 @@ -147,7 +147,6 @@ 現在のタブ(&L) Top, Bottom, Right True - Off 405, 3 3, 3, 3, 0 38, 12 From 60b546bd22d6ae76c2ec6e0ccefbfe00b58e708a Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 06:18:59 +0900 Subject: [PATCH 224/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E8=A9=B3=E7=B4=B0?= =?UTF-8?q?=E9=83=A8=E3=81=AE=E5=90=8D=E5=89=8D=E3=83=A9=E3=83=99=E3=83=AB?= =?UTF-8?q?=E3=82=92=E6=8A=95=E7=A8=BF=E8=80=85=E3=81=A8RT=E3=81=97?= =?UTF-8?q?=E3=81=9F=E3=83=A6=E3=83=BC=E3=82=B6=E3=83=BC=E3=81=A7=E5=88=86?= =?UTF-8?q?=E3=81=91=E3=81=9A=E3=81=AB=E8=A1=A8=E7=A4=BA=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Author と RetweetedBy で分割した場合にラベルの AutoEllipsis が正しく機能しない問題があったため撤回 --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/TweetDetailsView.Designer.cs | 49 ++++++------------------ OpenTween/TweetDetailsView.cs | 37 +++++------------- OpenTween/TweetDetailsView.resx | 53 +++++++------------------- 4 files changed, 35 insertions(+), 105 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 59b8e6f32..e5b7050b1 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Unreleased * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 + * CHG: 発言詳細部の名前ラベルを投稿者とRTしたユーザーで分けずに表示するように変更 * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 diff --git a/OpenTween/TweetDetailsView.Designer.cs b/OpenTween/TweetDetailsView.Designer.cs index 9c6dc0e3e..b725b7e2d 100644 --- a/OpenTween/TweetDetailsView.Designer.cs +++ b/OpenTween/TweetDetailsView.Designer.cs @@ -45,9 +45,7 @@ private void InitializeComponent() this.IconNameToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ReloadIconToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.SaveIconPictureToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); - this.AuthorNameLinkLabel = new System.Windows.Forms.LinkLabel(); - this.RetweetedByLinkLabel = new System.Windows.Forms.LinkLabel(); + this.NameLinkLabel = new System.Windows.Forms.LinkLabel(); this.PostBrowser = new System.Windows.Forms.WebBrowser(); this.ContextMenuPostBrowser = new System.Windows.Forms.ContextMenuStrip(this.components); this.SelectionSearchContextMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -83,7 +81,6 @@ private void InitializeComponent() this.TableLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.UserPicture)).BeginInit(); this.ContextMenuUserPicture.SuspendLayout(); - this.flowLayoutPanel1.SuspendLayout(); this.ContextMenuPostBrowser.SuspendLayout(); this.ContextMenuSource.SuspendLayout(); this.SuspendLayout(); @@ -92,7 +89,7 @@ private void InitializeComponent() // resources.ApplyResources(this.TableLayoutPanel1, "TableLayoutPanel1"); this.TableLayoutPanel1.Controls.Add(this.UserPicture, 0, 0); - this.TableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 1, 0); + this.TableLayoutPanel1.Controls.Add(this.NameLinkLabel, 1, 0); this.TableLayoutPanel1.Controls.Add(this.PostBrowser, 1, 1); this.TableLayoutPanel1.Controls.Add(this.DateTimeLabel, 2, 0); this.TableLayoutPanel1.Controls.Add(this.SourceLinkLabel, 3, 0); @@ -201,34 +198,16 @@ private void InitializeComponent() resources.ApplyResources(this.SaveIconPictureToolStripMenuItem, "SaveIconPictureToolStripMenuItem"); this.SaveIconPictureToolStripMenuItem.Click += new System.EventHandler(this.SaveIconPictureToolStripMenuItem_Click); // - // flowLayoutPanel1 + // NameLinkLabel // - resources.ApplyResources(this.flowLayoutPanel1, "flowLayoutPanel1"); - this.flowLayoutPanel1.Controls.Add(this.AuthorNameLinkLabel); - this.flowLayoutPanel1.Controls.Add(this.RetweetedByLinkLabel); - this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - // - // AuthorNameLinkLabel - // - this.AuthorNameLinkLabel.ActiveLinkColor = System.Drawing.SystemColors.ControlText; - resources.ApplyResources(this.AuthorNameLinkLabel, "AuthorNameLinkLabel"); - this.AuthorNameLinkLabel.AutoEllipsis = true; - this.AuthorNameLinkLabel.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline; - this.AuthorNameLinkLabel.LinkColor = System.Drawing.SystemColors.ControlText; - this.AuthorNameLinkLabel.Name = "AuthorNameLinkLabel"; - this.AuthorNameLinkLabel.TabStop = true; - this.AuthorNameLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.AuthorNameLinkLabel_LinkClicked); - // - // RetweetedByLinkLabel - // - this.RetweetedByLinkLabel.ActiveLinkColor = System.Drawing.SystemColors.ControlText; - resources.ApplyResources(this.RetweetedByLinkLabel, "RetweetedByLinkLabel"); - this.RetweetedByLinkLabel.AutoEllipsis = true; - this.RetweetedByLinkLabel.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline; - this.RetweetedByLinkLabel.LinkColor = System.Drawing.SystemColors.ControlText; - this.RetweetedByLinkLabel.Name = "RetweetedByLinkLabel"; - this.RetweetedByLinkLabel.TabStop = true; - this.RetweetedByLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.RetweetedByLinkLabel_LinkClicked); + this.NameLinkLabel.ActiveLinkColor = System.Drawing.SystemColors.ControlText; + resources.ApplyResources(this.NameLinkLabel, "NameLinkLabel"); + this.NameLinkLabel.AutoEllipsis = true; + this.NameLinkLabel.LinkBehavior = System.Windows.Forms.LinkBehavior.NeverUnderline; + this.NameLinkLabel.LinkColor = System.Drawing.SystemColors.ControlText; + this.NameLinkLabel.Name = "NameLinkLabel"; + this.NameLinkLabel.TabStop = true; + this.NameLinkLabel.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.NameLinkLabel_LinkClicked); // // PostBrowser // @@ -474,8 +453,6 @@ private void InitializeComponent() this.TableLayoutPanel1.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.UserPicture)).EndInit(); this.ContextMenuUserPicture.ResumeLayout(false); - this.flowLayoutPanel1.ResumeLayout(false); - this.flowLayoutPanel1.PerformLayout(); this.ContextMenuPostBrowser.ResumeLayout(false); this.ContextMenuSource.ResumeLayout(false); this.ResumeLayout(false); @@ -486,9 +463,6 @@ private void InitializeComponent() internal System.Windows.Forms.TableLayoutPanel TableLayoutPanel1; internal OTPictureBox UserPicture; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; - private System.Windows.Forms.LinkLabel AuthorNameLinkLabel; - private System.Windows.Forms.LinkLabel RetweetedByLinkLabel; internal System.Windows.Forms.WebBrowser PostBrowser; internal System.Windows.Forms.LinkLabel SourceLinkLabel; internal System.Windows.Forms.ContextMenuStrip ContextMenuPostBrowser; @@ -534,5 +508,6 @@ private void InitializeComponent() internal System.Windows.Forms.ToolStripMenuItem SourceCopyMenuItem; internal System.Windows.Forms.ToolStripMenuItem SourceUrlCopyMenuItem; private System.Windows.Forms.LinkLabel DateTimeLabel; + private System.Windows.Forms.LinkLabel NameLinkLabel; } } diff --git a/OpenTween/TweetDetailsView.cs b/OpenTween/TweetDetailsView.cs index 5151f44ac..f1aa2f2e3 100644 --- a/OpenTween/TweetDetailsView.cs +++ b/OpenTween/TweetDetailsView.cs @@ -94,8 +94,7 @@ public TweetDetailsView() this.TabStop = false; // 発言詳細部の初期化 - this.AuthorNameLinkLabel.Text = ""; - this.RetweetedByLinkLabel.Text = ""; + this.NameLinkLabel.Text = ""; this.DateTimeLabel.Text = ""; this.SourceLinkLabel.Text = ""; @@ -140,18 +139,10 @@ public async Task ShowPostDetails(PostClass post) nameText = ""; } nameText += post.ScreenName + "/" + post.Nickname; - this.AuthorNameLinkLabel.Text = nameText; - if (post.RetweetedId != null) - { - this.RetweetedByLinkLabel.Visible = true; - this.RetweetedByLinkLabel.Text = $"(RT:{post.RetweetedBy})"; - } - else - { - this.RetweetedByLinkLabel.Visible = false; - this.RetweetedByLinkLabel.Text = ""; - } + nameText += $" (RT:{post.RetweetedBy})"; + + this.NameLinkLabel.Text = nameText; var nameForeColor = SystemColors.ControlText; if (post.IsOwl && (SettingManager.Instance.Common.OneWayLove || post.IsDm)) @@ -161,10 +152,8 @@ public async Task ShowPostDetails(PostClass post) if (post.IsFav) nameForeColor = this.Theme.ColorFav; - this.AuthorNameLinkLabel.LinkColor = nameForeColor; - this.AuthorNameLinkLabel.ActiveLinkColor = nameForeColor; - this.RetweetedByLinkLabel.LinkColor = nameForeColor; - this.RetweetedByLinkLabel.ActiveLinkColor = nameForeColor; + this.NameLinkLabel.LinkColor = nameForeColor; + this.NameLinkLabel.ActiveLinkColor = nameForeColor; loadTasks.Add(this.SetUserPictureAsync(post.ImageUrl)); @@ -479,9 +468,8 @@ protected void RaiseStatusChanged(string statusText) private void TweetDetailsView_FontChanged(object sender, EventArgs e) { // OTBaseForm.GlobalFont による UI フォントの変更に対応 - var origFont = this.AuthorNameLinkLabel.Font; - this.AuthorNameLinkLabel.Font = new Font(this.Font.Name, origFont.Size, origFont.Style); - this.RetweetedByLinkLabel.Font = new Font(this.Font.Name, origFont.Size, origFont.Style); + var origFont = this.NameLinkLabel.Font; + this.NameLinkLabel.Font = new Font(this.Font.Name, origFont.Size, origFont.Style); } #region TableLayoutPanel1 @@ -1111,20 +1099,13 @@ private void SourceUrlCopyMenuItem_Click(object sender, EventArgs e) #endregion - private async void AuthorNameLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + private async void NameLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { var screenName = this.CurrentPost?.ScreenName; if (screenName != null) await this.Owner.ShowUserStatus(screenName, showInputDialog: false); } - private async void RetweetedByLinkLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - var screenName = this.CurrentPost?.RetweetedBy; - if (screenName != null) - await this.Owner.ShowUserStatus(screenName, showInputDialog: false); - } - private async void DateTimeLabel_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) { if (this.CurrentPost == null) diff --git a/OpenTween/TweetDetailsView.resx b/OpenTween/TweetDetailsView.resx index f6a907642..fe4e5d408 100644 --- a/OpenTween/TweetDetailsView.resx +++ b/OpenTween/TweetDetailsView.resx @@ -12,10 +12,6 @@ 511, 85 TweetDetailsView System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - AuthorNameLinkLabel - flowLayoutPanel1 - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 0 ContextMenuPostBrowser System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ContextMenuSource @@ -28,10 +24,6 @@ TableLayoutPanel1 System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 3 - flowLayoutPanel1 - TableLayoutPanel1 - System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 4 FollowContextMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 FollowToolStripMenuItem @@ -48,6 +40,10 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ListManageUserContextToolStripMenuItem3 System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + NameLinkLabel + TableLayoutPanel1 + System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 1 PostBrowser TableLayoutPanel1 System.Windows.Forms.WebBrowser, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -56,10 +52,6 @@ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 RemoveContextMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - RetweetedByLinkLabel - flowLayoutPanel1 - System.Windows.Forms.LinkLabel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 SaveIconPictureToolStripMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 SearchAtPostsDetailNameToolStripMenuItem @@ -128,15 +120,6 @@ TableLayoutPanel1 OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null 0 - Bottom - True - MS UI Gothic, 9pt, style=Bold - 3, 3 - 3, 3, 0, 0 - 135, 12 - 0 - AuthorNameLinkLabel - MiddleLeft 232, 386 17, 17 168, 48 @@ -153,14 +136,6 @@ 1 Label1 MiddleRight - True - GrowAndShrink - Fill - 56, 0 - 0, 0, 0, 0 - 346, 15 - 0 - False 231, 22 フォローする(&F) 231, 22 @@ -177,6 +152,14 @@ リスト管理(&L) 231, 22 リスト管理(&L) + Fill + MS UI Gothic, 9pt, style=Bold + 59, 3 + 3, 3, 3, 0 + 340, 12 + 0 + NameLinkLabel + MiddleLeft 発言本文 Fill 59, 20 @@ -186,16 +169,6 @@ 再読み込み(&R) 231, 22 フォロー解除(&N) - Bottom - True - MS UI Gothic, 9pt, style=Bold - NoControl - 141, 3 - 3, 3, 0, 0 - 141, 12 - 1 - RetweetedByLinkLabel - MiddleLeft 231, 22 保存(&I)... 231, 22 @@ -243,7 +216,7 @@ 4 Fill - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="UserPicture" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="flowLayoutPanel1" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="PostBrowser" Row="1" RowSpan="1" Column="1" ColumnSpan="3" /><Control Name="DateTimeLabel" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="SourceLinkLabel" Row="0" RowSpan="1" Column="3" ColumnSpan="1" /></Controls><Columns Styles="Absolute,56,Percent,100,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0,Percent,100" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="UserPicture" Row="0" RowSpan="2" Column="0" ColumnSpan="1" /><Control Name="NameLinkLabel" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="PostBrowser" Row="1" RowSpan="1" Column="1" ColumnSpan="3" /><Control Name="DateTimeLabel" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="SourceLinkLabel" Row="0" RowSpan="1" Column="3" ColumnSpan="1" /></Controls><Columns Styles="Absolute,56,Percent,100,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0,Percent,100,Absolute,20" /></TableLayoutSettings> 0, 0 2 511, 85 From 4f6497e7bf0c3ff799a6dfcf8e07f254c9e0fe89 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 07:11:45 +0900 Subject: [PATCH 225/402] =?UTF-8?q?release=E3=83=96=E3=83=A9=E3=83=B3?= =?UTF-8?q?=E3=83=81=E3=82=92AppVeyor=E3=81=AE=E3=83=93=E3=83=AB=E3=83=89?= =?UTF-8?q?=E5=AF=BE=E8=B1=A1=E3=81=8B=E3=82=89=E9=99=A4=E5=A4=96=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit タグに対するビルドが有効なため release ブランチでのビルドは不要になっている --- appveyor.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1470b19c1..676677d00 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -21,7 +21,6 @@ matrix: branches: only: - develop - - release - /^OpenTween.+/ # release tag for: From e401db7e4e929382b7cdea13fb1d3af561b21b9c Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 07:52:02 +0900 Subject: [PATCH 226/402] =?UTF-8?q?=E3=80=8CTwitter=20API=20v2=20=E3=81=AE?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=82=92=E6=9C=89=E5=8A=B9=E3=81=AB=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=80=8D=E3=81=AE=E3=82=AA=E3=83=97=E3=82=B7=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit API キーを自分で書き換えていて API v2 の有効化が完了できていないユーザー向け機能 --- OpenTween/Resources/ChangeLog.txt | 3 + .../Setting/Panel/ActionPanel.Designer.cs | 9 +++ OpenTween/Setting/Panel/ActionPanel.cs | 2 + OpenTween/Setting/Panel/ActionPanel.en.resx | 2 + OpenTween/Setting/Panel/ActionPanel.resx | 68 +++++++++++-------- OpenTween/Setting/SettingCommon.cs | 6 ++ OpenTween/Twitter.cs | 33 ++++++--- 7 files changed, 83 insertions(+), 40 deletions(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index e5b7050b1..7a0d2fb89 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,9 @@ ==== Unreleased * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 + * NEW: 設定画面に「Twitter API v2 の使用を有効にする」のチェックボックスを追加 + - デフォルトで API v2 が有効となり、通常は変更する必要はありません + - Twitter の API キーを独自に書き換えている場合で、Project への移行を完了できていない等の理由で API v2 を使用できない時はチェックを外してください * CHG: 発言詳細部の名前ラベルを投稿者とRTしたユーザーで分けずに表示するように変更 * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 diff --git a/OpenTween/Setting/Panel/ActionPanel.Designer.cs b/OpenTween/Setting/Panel/ActionPanel.Designer.cs index 5984e8de2..6553a7749 100644 --- a/OpenTween/Setting/Panel/ActionPanel.Designer.cs +++ b/OpenTween/Setting/Panel/ActionPanel.Designer.cs @@ -51,6 +51,7 @@ private void InitializeComponent() this.CheckCloseToExit = new System.Windows.Forms.CheckBox(); this.CheckMinimizeToTray = new System.Windows.Forms.CheckBox(); this.CheckReadOldPosts = new System.Windows.Forms.CheckBox(); + this.CheckEnableTwitterV2Api = new System.Windows.Forms.CheckBox(); this.GroupBox3.SuspendLayout(); this.SuspendLayout(); // @@ -205,6 +206,12 @@ private void InitializeComponent() this.CheckReadOldPosts.Name = "CheckReadOldPosts"; this.CheckReadOldPosts.UseVisualStyleBackColor = true; // + // CheckEnableTwitterV2Api + // + resources.ApplyResources(this.CheckEnableTwitterV2Api, "CheckEnableTwitterV2Api"); + this.CheckEnableTwitterV2Api.Name = "CheckEnableTwitterV2Api"; + this.CheckEnableTwitterV2Api.UseVisualStyleBackColor = true; + // // ActionPanel // resources.ApplyResources(this, "$this"); @@ -224,6 +231,7 @@ private void InitializeComponent() this.Controls.Add(this.CheckCloseToExit); this.Controls.Add(this.CheckMinimizeToTray); this.Controls.Add(this.CheckReadOldPosts); + this.Controls.Add(this.CheckEnableTwitterV2Api); this.Name = "ActionPanel"; this.GroupBox3.ResumeLayout(false); this.GroupBox3.PerformLayout(); @@ -256,5 +264,6 @@ private void InitializeComponent() internal System.Windows.Forms.CheckBox CheckCloseToExit; internal System.Windows.Forms.CheckBox CheckMinimizeToTray; internal System.Windows.Forms.CheckBox CheckReadOldPosts; + private System.Windows.Forms.CheckBox CheckEnableTwitterV2Api; } } diff --git a/OpenTween/Setting/Panel/ActionPanel.cs b/OpenTween/Setting/Panel/ActionPanel.cs index 40935ab57..196188475 100644 --- a/OpenTween/Setting/Panel/ActionPanel.cs +++ b/OpenTween/Setting/Panel/ActionPanel.cs @@ -48,6 +48,7 @@ public void LoadConfig(SettingCommon settingCommon, SettingLocal settingLocal) this.BrowserPathText.Text = settingLocal.BrowserPath; this.CheckCloseToExit.Checked = settingCommon.CloseToExit; this.CheckMinimizeToTray.Checked = settingCommon.MinimizeToTray; + this.CheckEnableTwitterV2Api.Checked = settingCommon.EnableTwitterV2Api; this.CheckFavRestrict.Checked = settingCommon.RestrictFavCheck; this.chkReadOwnPost.Checked = settingCommon.ReadOwnPost; this.CheckReadOldPosts.Checked = settingCommon.ReadOldPosts; @@ -90,6 +91,7 @@ public void SaveConfig(SettingCommon settingCommon, SettingLocal settingLocal) settingLocal.BrowserPath = this.BrowserPathText.Text.Trim(); settingCommon.CloseToExit = this.CheckCloseToExit.Checked; settingCommon.MinimizeToTray = this.CheckMinimizeToTray.Checked; + settingCommon.EnableTwitterV2Api = this.CheckEnableTwitterV2Api.Checked; settingCommon.RestrictFavCheck = this.CheckFavRestrict.Checked; settingCommon.ReadOwnPost = this.chkReadOwnPost.Checked; settingCommon.ReadOldPosts = this.CheckReadOldPosts.Checked; diff --git a/OpenTween/Setting/Panel/ActionPanel.en.resx b/OpenTween/Setting/Panel/ActionPanel.en.resx index e1a4a6060..c23c793e1 100644 --- a/OpenTween/Setting/Panel/ActionPanel.en.resx +++ b/OpenTween/Setting/Panel/ActionPanel.en.resx @@ -8,6 +8,8 @@ Open... 150, 16 Close to Exit application + 172, 16 + Enable use of Twitter API v2 149, 16 Check fav result strictly 106, 16 diff --git a/OpenTween/Setting/Panel/ActionPanel.resx b/OpenTween/Setting/Panel/ActionPanel.resx index 3a0b1857a..182050789 100644 --- a/OpenTween/Setting/Panel/ActionPanel.resx +++ b/OpenTween/Setting/Panel/ActionPanel.resx @@ -24,6 +24,10 @@ $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 12 + CheckEnableTwitterV2Api + $this + System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + 15 CheckFavRestrict $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -100,53 +104,59 @@ $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 10 - 185, 101 + 180, 113 228, 19 - 24 + 5 NoControl - 419, 100 + 414, 112 75, 21 - 25 + 6 参照 True NoControl - 23, 57 + 23, 63 171, 16 - 21 + 2 ×ボタンを押したときに終了する + True + NoControl + 21, 142 + 197, 16 + 7 + Twitter API v2 の使用を有効にする True NoControl - 23, 126 + 21, 167 183, 16 - 26 + 8 Fav操作結果を厳密にチェックする True NoControl - 23, 79 + 21, 88 170, 16 - 22 + 3 最小化したときにアイコン化する True NoControl - 23, 165 + 21, 212 180, 16 - 28 + 10 ユーザーのホームURLをタブで開く True NoControl - 23, 35 + 23, 38 145, 16 - 20 + 1 新着時に未読をクリアする True NoControl - 23, 187 + 21, 237 143, 16 - 29 + 11 自分の発言を既読にする - 24, 257 + 23, 316 473, 43 - 33 + 15 ホットキー True NoControl @@ -190,22 +200,22 @@ Win True NoControl - 24, 212 + 18, 265 142, 12 - 30 + 12 発言をダブルクリック時の動作 True NoControl - 23, 104 + 18, 116 60, 12 - 23 + 4 ブラウザパス True NoControl - 23, 145 + 23, 189 3, 0, 3, 5 340, 12 - 27 + 9 発言を再取得してFav結果を検証します。通信量が増えるのでOff推奨 なし Reply @@ -216,19 +226,19 @@ 関連発言表示 ユーザーのHomeを開く ステータスをWebで開く - 263, 209 + 257, 262 232, 20 - 31 + 13 True NoControl - 23, 235 + 21, 291 164, 16 - 32 + 14 マウスでのタブ移動を禁止する True NoControl 23, 13 100, 16 - 19 + 0 未読管理を行う diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index b16ebad13..f89f4af8b 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -156,6 +156,12 @@ private string Decrypt(string password) public bool TinyUrlResolve = true; public bool StartupVersion = true; public bool StartupFollowers = true; + + /// + /// Twitter API v2 の使用を有効にする + /// + public bool EnableTwitterV2Api { get; set; } = true; + public bool RestrictFavCheck = false; public bool AlwaysTop = false; public string CultureCode = ""; diff --git a/OpenTween/Twitter.cs b/OpenTween/Twitter.cs index 87ce8ec8c..d5aa0419a 100644 --- a/OpenTween/Twitter.cs +++ b/OpenTween/Twitter.cs @@ -510,22 +510,33 @@ public async Task GetHomeTimelineApi(bool read, HomeTabModel tab, bool more, boo var count = GetApiResultCount(MyCommon.WORKERTYPE.Timeline, more, startup); - var request = new GetTimelineRequest(this.UserId) + TwitterStatus[] statuses; + if (SettingManager.Instance.Common.EnableTwitterV2Api) { - MaxResults = count, - UntilId = more ? tab.OldestId.ToString() : null, - }; + var request = new GetTimelineRequest(this.UserId) + { + MaxResults = count, + UntilId = more ? tab.OldestId.ToString() : null, + }; - var response = await request.Send(this.Api.Connection) - .ConfigureAwait(false); + var response = await request.Send(this.Api.Connection) + .ConfigureAwait(false); - if (response.Data == null || response.Data.Length == 0) - return; + if (response.Data == null || response.Data.Length == 0) + return; - var tweetIds = response.Data.Select(x => x.Id).ToList(); + var tweetIds = response.Data.Select(x => x.Id).ToList(); - var statuses = await this.Api.StatusesLookup(tweetIds) - .ConfigureAwait(false); + statuses = await this.Api.StatusesLookup(tweetIds) + .ConfigureAwait(false); + } + else + { + var maxId = more ? tab.OldestId : (long?)null; + + statuses = await this.Api.StatusesHomeTimeline(count, maxId) + .ConfigureAwait(false); + } var minimumId = this.CreatePostsFromJson(statuses, MyCommon.WORKERTYPE.Timeline, tab, read); if (minimumId != null) From 84416e896744d83934214a4e24c1a614ad62ca99 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 15:45:11 +0900 Subject: [PATCH 227/402] =?UTF-8?q?=E3=82=BF=E3=83=96=E5=90=8D=E3=81=AE?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=8C=20TweenMain.listViewState=20?= =?UTF-8?q?=E3=81=AB=E5=8F=8D=E6=98=A0=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84?= =?UTF-8?q?=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://osdn.net/projects/opentween/ticket/45216 Fixes: 20d6826b ("ListViewのスクロール位置・選択状態を保持するTimelineListViewStateを追加") --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 7a0d2fb89..365e72f1a 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -9,6 +9,7 @@ * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 + * FIX: タブ名変更後にタイムラインを取得するとエラーが発生する不具合を修正 ==== Ver 2.6.0(2022/07/24) * NEW: Recentタブの発言の取得に Twitter API v2 を使用 diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 02a60382f..5cc1ace7e 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -5929,6 +5929,10 @@ public bool TabRename(string origTabName, [NotNullWhen(true)] out string? newTab this.statuses.RenameTab(origTabName, newTabName); + var state = this.listViewState[origTabName]; + this.listViewState.Remove(origTabName); + this.listViewState[newTabName] = state; + this.SaveConfigsCommon(); this.SaveConfigsTabs(); this.rclickTabName = newTabName; From 1fecc8cd74bc2544aff254094166e721ee9104e5 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 15:57:51 +0900 Subject: [PATCH 228/402] =?UTF-8?q?OpenTween=20v2.7.0=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 22 +++++++++++----------- OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index c988e93f5..65a658fe5 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.6.0.1")] +[assembly: AssemblyVersion("2.7.0.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 3a7f625bf..21be83480 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,18 +571,18 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Unreleased + ///==== Ver 2.7.0(2022/07/30) + /// * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 + /// * NEW: 設定画面に「Twitter API v2 の使用を有効にする」のチェックボックスを追加 + /// - デフォルトで API v2 が有効となり、通常は変更する必要はありません + /// - Twitter の API キーを独自に書き換えている場合で、Project への移行を完了できていない等の理由で API v2 を使用できない時はチェックを外してください + /// * CHG: 発言詳細部の名前ラベルを投稿者とRTしたユーザーで分けずに表示するように変更 + /// * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 + /// * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 + /// * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 + /// * FIX: タブ名変更後にタイムラインを取得するとエラーが発生する不具合を修正 /// - ///==== Ver 2.6.0(2022/07/24) - /// * NEW: Recentタブの発言の取得に Twitter API v2 を使用 - /// - 従来の API v1.1 と比べて、15分間に取得できる回数の制限が15→180回に緩和、一度に取得できる件数が200→100件になります - /// * NEW: RTしたユーザーのプロフィール・タイムラインを表示する機能をメニューに追加 (thx @kzlogos!) - /// * NEW: 発言詳細欄の名前やアイコンのクリックによるプロフィール表示に対応 - /// * NEW: クリップボード経由での複数枚の画像ファイル添付に対応 - /// * NEW: 画面上に表示する解像度に応じたプロフィール画像の取得に対応 - /// - 高DPI環境で表示した場合により高解像度のプロフィール画像が取得されるようになります - /// - リストのアイコンサイズを none に設定した場合、発言が選択されるまでプロフィール画像のダウンロードを行わなくなります - /// * NEW: 発言のダブルクリック時の動作に「Reply All」(@返信ALL [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + ///==== Ver 2 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 365e72f1a..875763b8d 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Unreleased +==== Ver 2.7.0(2022/07/30) * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 * NEW: 設定画面に「Twitter API v2 の使用を有効にする」のチェックボックスを追加 - デフォルトで API v2 が有効となり、通常は変更する必要はありません From 3b48fbde4d5496c0a6030faf7155f20a387a229c Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 16:05:53 +0900 Subject: [PATCH 229/402] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.7.1-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 6 +++--- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 65a658fe5..26dc4680e 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.7.0.0")] +[assembly: AssemblyVersion("2.7.0.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 21be83480..3f30a561d 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,6 +571,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Unreleased + /// ///==== Ver 2.7.0(2022/07/30) /// * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 /// * NEW: 設定画面に「Twitter API v2 の使用を有効にする」のチェックボックスを追加 @@ -580,9 +582,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 /// * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 /// * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 - /// * FIX: タブ名変更後にタイムラインを取得するとエラーが発生する不具合を修正 - /// - ///==== Ver 2 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: タブ名変更後にタイムラインを取得するとエラーが発生する不 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 875763b8d..2cfcc5038 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Unreleased + ==== Ver 2.7.0(2022/07/30) * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 * NEW: 設定画面に「Twitter API v2 の使用を有効にする」のチェックボックスを追加 diff --git a/appveyor.yml b/appveyor.yml index 676677d00..f1a03ecfa 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.6.0.{build} +version: 2.7.0.{build} os: Visual Studio 2022 From eef42e6e8e3e3be2884ada0277eee64c3a8d7bd1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 30 Jul 2022 23:05:59 +0900 Subject: [PATCH 230/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E6=9C=AC=E6=96=87?= =?UTF-8?q?=E3=81=AE=E7=BF=BB=E8=A8=B3=E6=99=82=E3=81=AB=E7=99=BA=E7=94=9F?= =?UTF-8?q?=E3=81=97=E3=81=9F=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=8C=E9=81=A9?= =?UTF-8?q?=E5=88=87=E3=81=AB=E5=87=A6=E7=90=86=E3=81=95=E3=82=8C=E3=81=AA?= =?UTF-8?q?=E3=81=84=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Api/MicrosoftTranslatorApi.cs | 3 ++- OpenTween/Resources/ChangeLog.txt | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenTween/Api/MicrosoftTranslatorApi.cs b/OpenTween/Api/MicrosoftTranslatorApi.cs index 363946841..6400a7ad7 100644 --- a/OpenTween/Api/MicrosoftTranslatorApi.cs +++ b/OpenTween/Api/MicrosoftTranslatorApi.cs @@ -128,7 +128,8 @@ public async Task UpdateAccessTokenIfExpired() using var response = await this.Http.SendAsync(request) .ConfigureAwait(false); - response.EnsureSuccessStatusCode(); + if (!response.IsSuccessStatusCode) + throw new WebApiException(response.StatusCode.ToString()); var accessToken = await response.Content.ReadAsStringAsync() .ConfigureAwait(false); diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 2cfcc5038..8e0243309 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Unreleased + * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 ==== Ver 2.7.0(2022/07/30) * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 From 0b9006535e36e262513ff9b78ea27e2e658f9b6f Mon Sep 17 00:00:00 2001 From: kzrnm Date: Thu, 11 Aug 2022 00:58:35 +0900 Subject: [PATCH 231/402] =?UTF-8?q?.editorconfig=20=E3=81=AB=20csproj=20?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .editorconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.editorconfig b/.editorconfig index 1c1266938..00bab1044 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,3 +1,8 @@ +[*.csproj] +indent_style = space +indent_size = 2 +tab_width = 2 + [*.cs] indent_style = space tab_width = 4 From 8b11e0d94311308282cee7498e884fd1d2c56150 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 28 Aug 2022 13:59:37 +0900 Subject: [PATCH 232/402] =?UTF-8?q?=E7=99=BA=E8=A8=80=E4=B8=80=E8=A6=A7?= =?UTF-8?q?=E3=81=AE=E6=8F=8F=E7=94=BB=E6=99=82=E3=81=AB=E3=83=87=E3=83=83?= =?UTF-8?q?=E3=83=89=E3=83=AD=E3=83=83=E3=82=AF=E3=81=8C=E7=99=BA=E7=94=9F?= =?UTF-8?q?=E3=81=99=E3=82=8B=E4=B8=8D=E5=85=B7=E5=90=88=E3=82=92=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=20(thx=20@Kazuki=5FAshiya!)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit STA thread 内での Mutex, WaitHandle によるロックはスレッドを完全に待機させる のではなく WM_PAINT などの一部のメッセージを処理しながら待機する動作になる。 これにより ImageCache.lockObject と HttpClient が内部で使用するロックとの間で デッドロックを生じさせていた。 参照: https://twitter.com/kim_upsilon/status/1561736832236150784 DrawItem イベントの処理中にはロックを使用しないのが最も望ましいが、暫定的な対処として ImageCache.lockObject のロック中に HttpClient.GetAsync を呼ばないように修正した。 Fixes: 92f0a891 ("ImageListViewItemを削除し通常のListViewItemのみを使用する") --- OpenTween/ImageCache.cs | 22 +++++++++------------- OpenTween/Resources/ChangeLog.txt | 1 + 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/OpenTween/ImageCache.cs b/OpenTween/ImageCache.cs index 690a7aced..76bfb639e 100644 --- a/OpenTween/ImageCache.cs +++ b/OpenTween/ImageCache.cs @@ -91,25 +91,21 @@ public Task DownloadImageAsync(string address, bool force = false) return Task.Run(() => { + Task? cachedImageTask; lock (this.lockObject) - { - this.InnerDictionary.TryGetValue(address, out var cachedImageTask); + this.InnerDictionary.TryGetValue(address, out cachedImageTask); - if (cachedImageTask != null) - { - if (force) - this.InnerDictionary.Remove(address); - else - return cachedImageTask; - } + if (cachedImageTask != null && !force) + return cachedImageTask; - cancelToken.ThrowIfCancellationRequested(); + cancelToken.ThrowIfCancellationRequested(); - var imageTask = this.FetchImageAsync(address, cancelToken); + var imageTask = this.FetchImageAsync(address, cancelToken); + + lock (this.lockObject) this.InnerDictionary[address] = imageTask; - return imageTask; - } + return imageTask; }, cancelToken); } diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 8e0243309..26c6ec9f5 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Unreleased + * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 ==== Ver 2.7.0(2022/07/30) From 63b2b4eb8af900fda779ae2f367416b8797ecb72 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 28 Aug 2022 14:56:23 +0900 Subject: [PATCH 233/402] =?UTF-8?q?=E3=82=B5=E3=83=A0=E3=83=8D=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E7=94=BB=E5=83=8F=E3=81=AE=E8=AA=AD=E3=81=BF=E8=BE=BC?= =?UTF-8?q?=E3=81=BF=E3=82=92=E6=98=8E=E7=A4=BA=E7=9A=84=E3=81=AB=E3=83=AF?= =?UTF-8?q?=E3=83=BC=E3=82=AB=E3=83=BC=E3=82=B9=E3=83=AC=E3=83=83=E3=83=89?= =?UTF-8?q?=E4=B8=8A=E3=81=A7=E8=A1=8C=E3=81=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TweetThumbnail.ShowThumbnailAsync メソッドは従来から Task を使用した非同期 メソッドとなっているが、Task.Run を明示的に使用していないことから HttpClient.GetAsync はメインスレッド上で実行される状態となっていた。 HttpClient.GetAsync は内部で WaitHandle によるロックを使用しており、 STA thread 上で使用する場合に問題があることや、発言一覧の選択位置が変化した 場合などで DrawItem イベントとサムネイル画像の表示処理は並列に実行される ことが多く、ImageCache クラスの修正前はデッドロックを生じさせる原因の一つと なっていた。 そのため、修正後は HttpClient.GetAsync を含む処理を明示的に Task.Run で ワーカースレッド上で実行されるようにした。 --- OpenTween.Tests/OpenTween.Tests.csproj | 1 + OpenTween.Tests/TweetThumbnailTest.cs | 22 +++++++--------------- OpenTween/OTPictureBox.cs | 2 +- OpenTween/TweetThumbnail.cs | 4 ++-- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/OpenTween.Tests/OpenTween.Tests.csproj b/OpenTween.Tests/OpenTween.Tests.csproj index a61fda3a5..3e6582c39 100644 --- a/OpenTween.Tests/OpenTween.Tests.csproj +++ b/OpenTween.Tests/OpenTween.Tests.csproj @@ -40,6 +40,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/OpenTween.Tests/TweetThumbnailTest.cs b/OpenTween.Tests/TweetThumbnailTest.cs index 9f274ec8b..04cd7e305 100644 --- a/OpenTween.Tests/TweetThumbnailTest.cs +++ b/OpenTween.Tests/TweetThumbnailTest.cs @@ -104,7 +104,7 @@ private void MyCommonSetup() MyCommon.EntryAssembly = mockAssembly.Object; } - [Fact] + [WinFormsFact] public void CreatePictureBoxTest() { using var thumbBox = new TweetThumbnail(); @@ -121,7 +121,7 @@ public void CreatePictureBoxTest() picbox.Dispose(); } - [Fact] + [WinFormsFact] public async Task CancelAsyncTest() { var post = new PostClass @@ -138,7 +138,6 @@ public async Task CancelAsyncTest() using var tokenSource = new CancellationTokenSource(); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); var task = thumbbox.ShowThumbnailAsync(post, tokenSource.Token); tokenSource.Cancel(); @@ -147,7 +146,7 @@ public async Task CancelAsyncTest() Assert.True(task.IsCanceled); } - [Theory] + [WinFormsTheory] [InlineData(0)] [InlineData(1)] [InlineData(2)] @@ -178,7 +177,7 @@ public void SetThumbnailCountTest(int count) Assert.Equal(count - 1, thumbbox.scrollBar.Maximum); } - [Fact] + [WinFormsFact] public async Task ShowThumbnailAsyncTest() { var post = new PostClass @@ -193,7 +192,6 @@ public async Task ShowThumbnailAsyncTest() using var thumbbox = new TweetThumbnail(); thumbbox.Initialize(this.CreateThumbnailGenerator()); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); Assert.Equal(0, thumbbox.scrollBar.Maximum); @@ -211,7 +209,7 @@ public async Task ShowThumbnailAsyncTest() Assert.Equal("", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[0])); } - [Fact] + [WinFormsFact] public async Task ShowThumbnailAsyncTest2() { var post = new PostClass @@ -227,7 +225,6 @@ public async Task ShowThumbnailAsyncTest2() using var thumbbox = new TweetThumbnail(); thumbbox.Initialize(this.CreateThumbnailGenerator()); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); Assert.Equal(1, thumbbox.scrollBar.Maximum); @@ -253,14 +250,12 @@ public async Task ShowThumbnailAsyncTest2() Assert.Equal("efgh", thumbbox.toolTip.GetToolTip(thumbbox.PictureBox[1])); } - [Fact] + [WinFormsFact] public async Task ThumbnailLoadingEventTest() { using var thumbbox = new TweetThumbnail(); thumbbox.Initialize(this.CreateThumbnailGenerator()); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var post = new PostClass { TextFromApi = "てすと", @@ -274,8 +269,6 @@ await TestUtils.NotRaisesAsync( () => thumbbox.ShowThumbnailAsync(post) ); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); - var post2 = new PostClass { TextFromApi = "てすと http://foo.example.com/abcd", @@ -292,7 +285,7 @@ await Assert.RaisesAsync( ); } - [Fact] + [WinFormsFact] public async Task ScrollTest() { var post = new PostClass @@ -308,7 +301,6 @@ public async Task ScrollTest() using var thumbbox = new TweetThumbnail(); thumbbox.Initialize(this.CreateThumbnailGenerator()); - SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); await thumbbox.ShowThumbnailAsync(post); Assert.Equal(0, thumbbox.scrollBar.Minimum); diff --git a/OpenTween/OTPictureBox.cs b/OpenTween/OTPictureBox.cs index 5ebb65140..21a775323 100644 --- a/OpenTween/OTPictureBox.cs +++ b/OpenTween/OTPictureBox.cs @@ -112,7 +112,7 @@ public async Task SetImageFromTask(Func> imageTask, bool useSt if (useStatusImage) this.ShowInitialImage(); - var image = await imageTask(); + var image = await Task.Run(imageTask); if (id == this.currentImageTaskId) this.Image = image; diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index dddb955cb..c3b839918 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -131,8 +131,8 @@ private string GetImageSearchUriGoogle(string image_uri) private string GetImageSearchUriSauceNao(string imageUri) => @"https://saucenao.com/search.php?url=" + Uri.EscapeDataString(imageUri); - protected virtual Task> GetThumbailInfoAsync(PostClass post, CancellationToken token) - => this.ThumbGenerator.GetThumbnailsAsync(post, token); + protected async virtual Task> GetThumbailInfoAsync(PostClass post, CancellationToken token) + => await Task.Run(() => this.ThumbGenerator.GetThumbnailsAsync(post, token)); /// /// 表示するサムネイルの数を設定する From 341e11e63b0ebe94c1619de82de1c9915ab551f1 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 3 Sep 2022 01:22:05 +0900 Subject: [PATCH 234/402] =?UTF-8?q?OpenTween=20v2.7.1=20=E3=83=AA=E3=83=AA?= =?UTF-8?q?=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 8 ++++---- OpenTween/Resources/ChangeLog.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 26dc4680e..10392a6e2 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.7.0.1")] +[assembly: AssemblyVersion("2.7.1.0")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index 3f30a561d..baa0084e9 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,7 +571,9 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// - ///==== Unreleased + ///==== Ver 2.7.1(2022/09/03) + /// * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) + /// * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 /// ///==== Ver 2.7.0(2022/07/30) /// * NEW: 発言詳細部の日時ラベルをクリックするとWebブラウザを起動してツイートを表示する機能を追加 @@ -580,9 +582,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// - Twitter の API キーを独自に書き換えている場合で、Project への移行を完了できていない等の理由で API v2 を使用できない時はチェックを外してください /// * CHG: 発言詳細部の名前ラベルを投稿者とRTしたユーザーで分けずに表示するように変更 /// * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 - /// * FIX: 読み込み中の待機ダイアログを表示する際にエラーが発生する不具合を修正 - /// * FIX: Recentタブの読み込み時にエラーダイアログが表示される場合がある不具合を修正 - /// * FIX: タブ名変更後にタイムラインを取得するとエラーが発生する不 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 26c6ec9f5..533eb13a4 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,6 @@ 更新履歴 -==== Unreleased +==== Ver 2.7.1(2022/09/03) * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 From b73bb0f5e4ed627be85f70e19eb01ab2233212c8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 3 Sep 2022 01:26:06 +0900 Subject: [PATCH 235/402] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=20v2.7.2-dev=20=E9=96=8B=E7=99=BA=E9=96=8B=E5=A7=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Properties/AssemblyInfo.cs | 2 +- OpenTween/Properties/Resources.Designer.cs | 5 +++-- OpenTween/Resources/ChangeLog.txt | 2 ++ appveyor.yml | 2 +- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs index 10392a6e2..4b29abd38 100644 --- a/OpenTween/Properties/AssemblyInfo.cs +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -22,7 +22,7 @@ // 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です [assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] -[assembly: AssemblyVersion("2.7.1.0")] +[assembly: AssemblyVersion("2.7.1.1")] [assembly: InternalsVisibleTo("OpenTween.Tests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/OpenTween/Properties/Resources.Designer.cs b/OpenTween/Properties/Resources.Designer.cs index baa0084e9..6d36018e1 100644 --- a/OpenTween/Properties/Resources.Designer.cs +++ b/OpenTween/Properties/Resources.Designer.cs @@ -571,6 +571,8 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// /// 更新履歴 /// + ///==== Unreleased + /// ///==== Ver 2.7.1(2022/09/03) /// * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) /// * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 @@ -581,8 +583,7 @@ internal static string ChangeIconToolStripMenuItem_Confirm { /// - デフォルトで API v2 が有効となり、通常は変更する必要はありません /// - Twitter の API キーを独自に書き換えている場合で、Project への移行を完了できていない等の理由で API v2 を使用できない時はチェックを外してください /// * CHG: 発言詳細部の名前ラベルを投稿者とRTしたユーザーで分けずに表示するように変更 - /// * FIX: タブの移動後に発言一覧が空の表示になる不具合を修正 - /// * FIX: [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// * FIX: タブの移動後に発言一覧が空の表 [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 /// internal static string ChangeLog { get { diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 533eb13a4..3c93aae43 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,5 +1,7 @@ 更新履歴 +==== Unreleased + ==== Ver 2.7.1(2022/09/03) * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) * FIX: 発言本文の翻訳時に発生したエラーが適切に処理されない不具合を修正 diff --git a/appveyor.yml b/appveyor.yml index f1a03ecfa..6f056819e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.7.0.{build} +version: 2.7.1.{build} os: Visual Studio 2022 From faf53c43a2102984a0b4753b7808bc3e71dfdd80 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 1 Oct 2022 17:20:09 +0900 Subject: [PATCH 236/402] =?UTF-8?q?build-zip-archive.ps1=20=E5=AE=9F?= =?UTF-8?q?=E8=A1=8C=E6=99=82=E3=81=AB=20msbuild,=20csc=20=E3=81=AE?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7=E3=83=B3=E3=82=92=E5=87=BA?= =?UTF-8?q?=E5=8A=9B=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reproducible Build で問題が発生した時の調査用 --- tools/build-zip-archive.ps1 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tools/build-zip-archive.ps1 b/tools/build-zip-archive.ps1 index a2f8087f1..b49a628fe 100644 --- a/tools/build-zip-archive.ps1 +++ b/tools/build-zip-archive.ps1 @@ -84,6 +84,10 @@ Function Build-Package([String[]] $Path, [String] $DestPath) { Compress-Archive -Force -Path $Path -DestinationPath $DestPath } +Function Get-CommandVersion([String] $Name) { + Get-Command -Name $Name | Select -Property Name, @{Name='ProductVersion'; Expression={$_.FileVersionInfo.ProductVersion}} +} + Generate-Serializer Build-SateliteAssembly -Culture en @@ -95,4 +99,13 @@ Build-Package -Path $includePaths -DestPath $DestPath Write-Host Write-Host "Build success!" -Get-FileHash -Algorithm SHA256 $destPath | Format-List +@( + Get-CommandVersion 'msbuild.exe' + Get-CommandVersion 'csc.exe' + Get-CommandVersion 'sgen.exe' + [PSCustomObject]@{ + Name = 'SOURCE_DATE_EPOCH' + Value = $timestamp + } + Get-FileHash -Algorithm SHA256 $destPath +) | Format-List From b549174ddedee3e07da6d85cd3dd00654fd0f790 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 1 Oct 2022 17:58:34 +0900 Subject: [PATCH 237/402] =?UTF-8?q?AppVeyor=20=E3=81=A7=E3=81=AE=20Pull=20?= =?UTF-8?q?Request=20=E3=81=AE=E3=83=93=E3=83=AB=E3=83=89=E6=99=82?= =?UTF-8?q?=E3=81=AB=20SOURCE=5FDATE=5FEPOCH=20=E3=81=8C=E6=AD=A3=E3=81=97?= =?UTF-8?q?=E3=81=84=E6=99=82=E5=88=BB=E3=81=AB=E3=81=AA=E3=82=89=E3=81=AA?= =?UTF-8?q?=E3=81=84=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 7 ++++++- tools/build-zip-archive.ps1 | 5 +++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 6f056819e..e2d8f48c6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -83,6 +83,11 @@ after_test: } else { $destPath = 'OpenTween_dev-' + $env:APPVEYOR_BUILD_NUMBER + '.zip' } - .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -AssemblyInfo $assemblyInfo -DestPath $destPath + if ($env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT -ne $null) { + $headCommit = $env:APPVEYOR_PULL_REQUEST_HEAD_COMMIT + } else { + $headCommit = 'HEAD' + } + .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -AssemblyInfo $assemblyInfo -DestPath $destPath -HeadCommit $headCommit # vim: et fenc=utf-8 sts=2 sw=2 ts=2 diff --git a/tools/build-zip-archive.ps1 b/tools/build-zip-archive.ps1 index b49a628fe..7678695ae 100644 --- a/tools/build-zip-archive.ps1 +++ b/tools/build-zip-archive.ps1 @@ -30,7 +30,8 @@ Param( [Parameter(Mandatory = $true)][String] $BinDir, [Parameter(Mandatory = $true)][String] $ObjDir, [Parameter(Mandatory = $true)][String] $AssemblyInfo, - [Parameter(Mandatory = $true)][String] $DestPath + [Parameter(Mandatory = $true)][String] $DestPath, + [String] $HeadCommit = 'HEAD' ) Set-StrictMode -Version 3.0 @@ -70,7 +71,7 @@ Function Get-SourceDateEpoch() { # ローカルのタイムゾーンの日時でタイムスタンプが記録されるため、わざとタイムゾーンを指定していない。 # これにより、生成される ZIP アーカイブには UTC での $sourceDateEpoch に相当する日時が記録されるようになる $unixEpoch = Get-Date "1970/01/01 00:00:00" - $sourceDateUnixtime = [int](Invoke-NativeCommand "git log -1 --pretty=%ct") + $sourceDateUnixtime = [int](Invoke-NativeCommand "git log -1 --pretty=%ct ${HeadCommit}") $sourceDateEpoch = $unixEpoch.AddSeconds($sourceDateUnixtime) return $sourceDateEpoch } From 9a4d0566af6bf20c58476cd17e6c7dc87a3a7bff Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 5 Nov 2022 04:08:58 +0900 Subject: [PATCH 238/402] =?UTF-8?q?OpenTween.XmlSerializer.dll=20=E3=81=AE?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E3=82=92=E5=BB=83=E6=AD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/OpenTween.csproj | 14 ++---- OpenTween/Setting/SettingAtIdList.cs | 2 + OpenTween/Setting/SettingCommon.cs | 1 + OpenTween/Setting/SettingLocal.cs | 1 + OpenTween/Setting/SettingTabs.cs | 1 + OpenTween/XmlSerializerContract.cs | 73 ++++++++++++++++++++++++++++ tools/build-zip-archive.ps1 | 11 +---- tools/generate-serializer.ps1 | 65 ------------------------- 8 files changed, 82 insertions(+), 86 deletions(-) create mode 100644 OpenTween/XmlSerializerContract.cs delete mode 100644 tools/generate-serializer.ps1 diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index cb4691fdf..0ba0fd5a6 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -22,7 +22,7 @@ TRACE;DEBUG prompt 4 - Auto + Off false OpenTween.ruleset @@ -33,7 +33,7 @@ TRACE prompt 4 - On + Off false false @@ -478,6 +478,7 @@ + @@ -810,13 +811,4 @@ - - - - - - - - - \ No newline at end of file diff --git a/OpenTween/Setting/SettingAtIdList.cs b/OpenTween/Setting/SettingAtIdList.cs index 08ab3c4f9..2fdecf0c2 100644 --- a/OpenTween/Setting/SettingAtIdList.cs +++ b/OpenTween/Setting/SettingAtIdList.cs @@ -30,9 +30,11 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Xml.Serialization; namespace OpenTween { + [XmlSerializerAssembly(null, null)] // OpenTween アセンブリ内の XmlSerializerContract を使用させる public class SettingAtIdList : SettingBase { #region Settingクラス基本 diff --git a/OpenTween/Setting/SettingCommon.cs b/OpenTween/Setting/SettingCommon.cs index f89f4af8b..a3131e527 100644 --- a/OpenTween/Setting/SettingCommon.cs +++ b/OpenTween/Setting/SettingCommon.cs @@ -34,6 +34,7 @@ namespace OpenTween { + [XmlSerializerAssembly(null, null)] // OpenTween アセンブリ内の XmlSerializerContract を使用させる public class SettingCommon : SettingBase { #region "Settingクラス基本" diff --git a/OpenTween/Setting/SettingLocal.cs b/OpenTween/Setting/SettingLocal.cs index ec3ee5cf1..8c085b0f1 100644 --- a/OpenTween/Setting/SettingLocal.cs +++ b/OpenTween/Setting/SettingLocal.cs @@ -36,6 +36,7 @@ namespace OpenTween { + [XmlSerializerAssembly(null, null)] // OpenTween アセンブリ内の XmlSerializerContract を使用させる public class SettingLocal : SettingBase { #region Settingクラス基本 diff --git a/OpenTween/Setting/SettingTabs.cs b/OpenTween/Setting/SettingTabs.cs index c40d091eb..f8974b99a 100644 --- a/OpenTween/Setting/SettingTabs.cs +++ b/OpenTween/Setting/SettingTabs.cs @@ -35,6 +35,7 @@ namespace OpenTween { + [XmlSerializerAssembly(null, null)] // OpenTween アセンブリ内の XmlSerializerContract を使用させる public class SettingTabs : SettingBase { #region Settingクラス基本 diff --git a/OpenTween/XmlSerializerContract.cs b/OpenTween/XmlSerializerContract.cs new file mode 100644 index 000000000..b85d6977e --- /dev/null +++ b/OpenTween/XmlSerializerContract.cs @@ -0,0 +1,73 @@ +// OpenTween - Client of Twitter +// Copyright (c) 2022 kim_upsilon (@kim_upsilon) +// All rights reserved. +// +// This file is part of OpenTween. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 3 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program. If not, see , or write to +// the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, +// Boston, MA 02110-1301, USA. + +using System; +using System.Collections; +using System.Xml.Serialization; + +#nullable enable + +namespace Microsoft.Xml.Serialization.GeneratedAssembly +{ + /// + /// OpenTween.XmlSerializer.dll のロードを防ぐための偽の XmlSerializerContract クラス + /// + /// + /// このクラスでは が常に false を返すため、 + /// は実行時にシリアライザを動的に生成します。 + /// + public class XmlSerializerContract : XmlSerializerImplementation + { + public override XmlSerializationReader Reader { get; } = new FakeXmlSerializerReader(); + + public override XmlSerializationWriter Writer { get; } = new FakeXmlSerializerWriter(); + + public override Hashtable ReadMethods { get; } = new(); + + public override Hashtable WriteMethods { get; } = new(); + + public override Hashtable TypedSerializers { get; } = new(); + + public override bool CanSerialize(Type type) + => false; + + public override XmlSerializer? GetSerializer(Type type) + => null; + } + + public class FakeXmlSerializerReader : XmlSerializationReader + { + protected override void InitCallbacks() + { + } + + protected override void InitIDs() + { + } + } + + public class FakeXmlSerializerWriter : XmlSerializationWriter + { + protected override void InitCallbacks() + { + } + } +} diff --git a/tools/build-zip-archive.ps1 b/tools/build-zip-archive.ps1 index 7678695ae..502935218 100644 --- a/tools/build-zip-archive.ps1 +++ b/tools/build-zip-archive.ps1 @@ -40,7 +40,6 @@ $ErrorActionPreference = 'Stop' $assemblyName = "OpenTween" $exePath = Join-Path $BinDir "${assemblyName}.exe" -$sgenOpts = "/type:${assemblyName}.SettingAtIdList /type:${assemblyName}.SettingCommon /type:${assemblyName}.SettingLocal /type:${assemblyName}.SettingTabs" $includeFiles = @( "en\", "Icons\", @@ -49,17 +48,11 @@ $includeFiles = @( "LICENSE.ja", "LICENSE.LGPL-3", "${assemblyName}.exe", - "${assemblyName}.exe.config", - "${assemblyName}.XmlSerializers.dll" + "${assemblyName}.exe.config" ) . .\tools\functions.ps1 -Function Generate-Serializer() { - # OpenTween.XmlSerializers.dll の生成 - .\tools\generate-serializer.ps1 -ExePath $exePath -SgenOpts $sgenOpts -} - Function Build-SateliteAssembly([String] $Culture) { # OpenTween.resources.dll の生成(カルチャ別) $sateliteAssemblyPath = Join-Path $BinDir "${Culture}\${assemblyName}.resources.dll" @@ -89,7 +82,6 @@ Function Get-CommandVersion([String] $Name) { Get-Command -Name $Name | Select -Property Name, @{Name='ProductVersion'; Expression={$_.FileVersionInfo.ProductVersion}} } -Generate-Serializer Build-SateliteAssembly -Culture en $includePaths = $includeFiles | % { Join-Path $BinDir $_ } @@ -103,7 +95,6 @@ Write-Host "Build success!" @( Get-CommandVersion 'msbuild.exe' Get-CommandVersion 'csc.exe' - Get-CommandVersion 'sgen.exe' [PSCustomObject]@{ Name = 'SOURCE_DATE_EPOCH' Value = $timestamp diff --git a/tools/generate-serializer.ps1 b/tools/generate-serializer.ps1 deleted file mode 100644 index 577057eca..000000000 --- a/tools/generate-serializer.ps1 +++ /dev/null @@ -1,65 +0,0 @@ -# OpenTween - Client of Twitter -# Copyright (c) 2021 kim_upsilon (@kim_upsilon) -# All rights reserved. -# -# This file is part of OpenTween. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see , or write to -# the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -# Boston, MA 02110-1301, USA. - -# -# Reproducible Build に対応した OpenTween.XmlSerializers.dll の生成を行うスクリプト -# -# 使い方: -# .\tools\generate-serializer.ps1 -ExePath ".\OpenTween\bin\Debug\OpenTween.exe" -SgenOpts "/type:OpenTween.SettingCommon" -# - -Param( - [Parameter(Mandatory = $true)][String] $ExePath, - [String] $SgenOpts = "" -) - -Set-StrictMode -Version 3.0 -$ErrorActionPreference = 'Stop' - -$binDir = Split-Path -Parent $ExePath -$exeName = Split-Path -Leaf $ExePath - -$dllName = $exeName -replace "\.exe$", ".XmlSerializers.dll" -$dllPath = Join-Path $binDir $dllName - -. .\tools\functions.ps1 - -Function Generate-Serializer() { - $tempDirName = "temp" - $tempDir = Join-Path $binDir $tempDirName - $tempExePath = Join-Path $tempDir $exeName - - # sgen は *.exe と同じディレクトリにソースコードを書き出すため、作業用のディレクトリを用意してビルドを実行する - Remove-Item -Recurse $tempDir -ErrorAction Ignore - New-Item -ItemType "directory" -Path $binDir -Name $tempDirName | Out-Null - Copy-Item $ExePath -Destination $tempDir - - # sgen が実行する C# コンパイラは Roslyn ではないため /deterministic オプションに対応していない。 - # sgen の /keep オプションによってソースコードと csc に渡すコマンドラインオプションが書き出されるため、これを使用して改めて Roslyn でコンパイルし直す - Invoke-NativeCommand "sgen /nologo /silent /keep $SgenOpts $tempExePath" - $cmdlinePath = Join-Path $tempDir "*.cmdline" - Invoke-NativeCommand "csc -nologo -warn:1 -deterministic $(Get-Content $cmdlinePath)" - - Copy-Item $(Join-Path $tempDir $dllName) -Destination $binDir - Remove-Item -Recurse $tempDir -} - -Generate-Serializer From ac9c185cf7528ec92355c704f513d02ea4db3a0e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 26 Nov 2022 23:23:47 +0900 Subject: [PATCH 239/402] =?UTF-8?q?=E3=83=87=E3=83=90=E3=83=83=E3=82=B0?= =?UTF-8?q?=E6=83=85=E5=A0=B1=E3=81=ABPortable=20PDB=E3=82=92=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/OpenTween.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 0ba0fd5a6..626f553fc 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -16,7 +16,7 @@ true - full + portable false bin\Debug\ TRACE;DEBUG @@ -27,7 +27,7 @@ OpenTween.ruleset - pdbonly + portable true bin\Release\ TRACE From 508b954828c48ab2cba09077eb819726ef30f33e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Nov 2022 03:36:42 +0900 Subject: [PATCH 240/402] =?UTF-8?q?=E9=87=8D=E8=A4=87=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=83=AA=E3=82=BD=E3=83=BC=E3=82=B9=E3=82=92=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/HashtagManage.resx | 20 -------------- OpenTween/ListAvailable.resx | 8 ------ OpenTween/ListManage.resx | 52 ------------------------------------ OpenTween/OpenURL.resx | 4 --- 4 files changed, 84 deletions(-) diff --git a/OpenTween/HashtagManage.resx b/OpenTween/HashtagManage.resx index a5275e067..2869bcdab 100644 --- a/OpenTween/HashtagManage.resx +++ b/OpenTween/HashtagManage.resx @@ -19,25 +19,17 @@ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 7 Cancel_Button - Cancel_Button - TableLayoutButtons TableLayoutButtons System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 0 0 CheckNotAddToAtReply $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 2 CheckPermanent - CheckPermanent GroupHashtag - GroupHashtag - System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 8 - 8 DeleteButton GroupHashtag System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -59,25 +51,17 @@ System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 0 Label1 - Label1 - GroupDetail GroupDetail System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 2 2 Label3 GroupHashtag System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 OK_Button - OK_Button TableLayoutButtons - TableLayoutButtons - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 - 1 PermCancel_Button TableLayoutPanel2 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -107,12 +91,8 @@ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 2 UseHashText - UseHashText - GroupDetail GroupDetail System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 1 NoControl 240, 18 diff --git a/OpenTween/ListAvailable.resx b/OpenTween/ListAvailable.resx index 69d9544b4..108f36a46 100644 --- a/OpenTween/ListAvailable.resx +++ b/OpenTween/ListAvailable.resx @@ -15,12 +15,8 @@ ListAvailable OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null Cancel_Button - Cancel_Button - TableLayoutPanel1 TableLayoutPanel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 1 DescriptionText $this @@ -63,12 +59,8 @@ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 10 OK_Button - OK_Button - TableLayoutPanel1 TableLayoutPanel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 0 0 RefreshButton $this diff --git a/OpenTween/ListManage.resx b/OpenTween/ListManage.resx index 17cb49b93..9f8d3267e 100644 --- a/OpenTween/ListManage.resx +++ b/OpenTween/ListManage.resx @@ -19,12 +19,8 @@ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 7 CancelEditButton - CancelEditButton - ListGroup ListGroup System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 1 CloseButton $this @@ -39,52 +35,32 @@ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 4 DescriptionText - DescriptionText - ListGroup ListGroup System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 11 11 EditCheckBox $this System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 1 GetMoreUsersButton - GetMoreUsersButton - MemberGroup MemberGroup System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 1 GroupBox2 ListGroup System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 2 Label1 - Label1 ListGroup - ListGroup - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 0 - 0 - Label10 Label10 ListGroup - ListGroup - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 10 - 10 Label12 - Label12 - ListGroup ListGroup System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 12 12 Label13 UserGroup @@ -107,29 +83,17 @@ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 3 Label4 - Label4 - ListGroup ListGroup System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 8 8 Label5 - Label5 - UserGroup UserGroup System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 16 16 Label6 - Label6 ListGroup - ListGroup - System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 9 - 9 Label8 UserGroup System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 @@ -155,32 +119,20 @@ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 6 NameTextBox - NameTextBox - ListGroup ListGroup System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 7 - 7 - OKEditButton OKEditButton ListGroup - ListGroup - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 3 - 3 PrivateRadioButton GroupBox2 System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 0 PublicRadioButton - PublicRadioButton - GroupBox2 GroupBox2 System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 1 RefreshListsButton $this @@ -211,13 +163,9 @@ OpenTween.OTPictureBox, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null 1 UserList - UserList MemberGroup - MemberGroup - System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Windows.Forms.ListBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 0 - 0 UserLocation UserGroup System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 diff --git a/OpenTween/OpenURL.resx b/OpenTween/OpenURL.resx index 73765a39c..8a3e89a83 100644 --- a/OpenTween/OpenURL.resx +++ b/OpenTween/OpenURL.resx @@ -17,12 +17,8 @@ OpenURL OpenTween.OTBaseForm, OpenTween, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null Cancel_Button - Cancel_Button - TableLayoutPanel1 TableLayoutPanel1 System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1 1 OK_Button TableLayoutPanel1 From f17f1e672bbf8d8304d1a2113e1ffda6faaa432b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Nov 2022 03:40:53 +0900 Subject: [PATCH 241/402] =?UTF-8?q?=E3=83=93=E3=83=AB=E3=83=89=E6=99=82?= =?UTF-8?q?=E3=81=AB=E4=BD=BF=E7=94=A8=E3=81=97=E3=81=9F=E3=83=A9=E3=83=B3?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=A0=E3=81=AE=E3=83=90=E3=83=BC=E3=82=B8?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E6=83=85=E5=A0=B1=E3=82=92=E5=87=BA=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/build-zip-archive.ps1 | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/build-zip-archive.ps1 b/tools/build-zip-archive.ps1 index 502935218..27f25e0f2 100644 --- a/tools/build-zip-archive.ps1 +++ b/tools/build-zip-archive.ps1 @@ -82,6 +82,16 @@ Function Get-CommandVersion([String] $Name) { Get-Command -Name $Name | Select -Property Name, @{Name='ProductVersion'; Expression={$_.FileVersionInfo.ProductVersion}} } +Function Get-RuntimeVersion() { + return [PSCustomObject]@{ + Name = 'RuntimeVersion' + Value = [Attribute]::GetCustomAttribute( + [Object].Assembly, + [System.Reflection.AssemblyInformationalVersionAttribute] + ).InformationalVersion + } +} + Build-SateliteAssembly -Culture en $includePaths = $includeFiles | % { Join-Path $BinDir $_ } @@ -95,6 +105,7 @@ Write-Host "Build success!" @( Get-CommandVersion 'msbuild.exe' Get-CommandVersion 'csc.exe' + Get-RuntimeVersion [PSCustomObject]@{ Name = 'SOURCE_DATE_EPOCH' Value = $timestamp From 8189667875783c46703cf57c3b1210afd33dc2bd Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sun, 27 Nov 2022 04:05:27 +0900 Subject: [PATCH 242/402] =?UTF-8?q?AppVeyor=E3=81=A7=E5=87=BA=E5=8A=9B?= =?UTF-8?q?=E3=81=99=E3=82=8BArtifact=E3=81=ABPDB=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=A4=E3=83=AB=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- appveyor.yml | 5 +++++ tools/build-zip-archive.ps1 | 2 ++ 2 files changed, 7 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index e2d8f48c6..f13edc956 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -36,6 +36,8 @@ for: artifacts: - name: OpenTween.zip path: OpenTween_dev-$(APPVEYOR_BUILD_NUMBER).zip + - name: OpenTween.pdb + path: OpenTween.pdb - # for release build matrix: only: @@ -44,6 +46,8 @@ for: artifacts: - name: OpenTween.zip path: $(APPVEYOR_REPO_TAG_NAME).zip + - name: OpenTween.pdb + path: OpenTween.pdb build: project: OpenTween.sln @@ -89,5 +93,6 @@ after_test: $headCommit = 'HEAD' } .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -AssemblyInfo $assemblyInfo -DestPath $destPath -HeadCommit $headCommit + Copy-Item ($binDir + 'OpenTween.pdb') -Destination '.\' # vim: et fenc=utf-8 sts=2 sw=2 ts=2 diff --git a/tools/build-zip-archive.ps1 b/tools/build-zip-archive.ps1 index 27f25e0f2..804e1e509 100644 --- a/tools/build-zip-archive.ps1 +++ b/tools/build-zip-archive.ps1 @@ -40,6 +40,7 @@ $ErrorActionPreference = 'Stop' $assemblyName = "OpenTween" $exePath = Join-Path $BinDir "${assemblyName}.exe" +$pdbPath = Join-Path $BinDir "${assemblyName}.pdb" $includeFiles = @( "en\", "Icons\", @@ -111,4 +112,5 @@ Write-Host "Build success!" Value = $timestamp } Get-FileHash -Algorithm SHA256 $destPath + Get-FileHash -Algorithm SHA256 $pdbPath ) | Format-List From 17248a55c56f53adb94532efa16f2beae6964989 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Tue, 29 Nov 2022 00:47:14 +0900 Subject: [PATCH 243/402] =?UTF-8?q?GitHub=20Actions=E3=81=AEWorkflow?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 174 ++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..4816cdbc6 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,174 @@ +name: Build + +on: + push: + branches: ['develop', 'release'] + pull_request: + +env: + NUGET_PACKAGES: ${{ github.workspace }}/.nuget/packages + +jobs: + build: + runs-on: windows-2022 + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + + - name: Set configuration env + shell: pwsh + run: | + if ($env:GITHUB_REF -eq 'refs/heads/release') { + echo 'CONFIGURATION=Release' >> $env:GITHUB_ENV + } else { + echo 'CONFIGURATION=Debug' >> $env:GITHUB_ENV + } + + - uses: actions/cache@v3 + with: + path: ${{ github.workspace }}/.nuget/packages + key: nuget-${{ hashFiles('*/*.csproj') }} + restore-keys: | + nuget- + + - name: Build + shell: pwsh + run: | + msbuild /target:restore,build "/p:Configuration=$($env:CONFIGURATION)" /verbosity:minimal + + - name: Upload build result + uses: actions/upload-artifact@v3 + with: + name: build + path: | + ./OpenTween/bin/ + ./OpenTween/obj/ + ./OpenTween.Tests/bin/ + retention-days: 1 + + test: + runs-on: windows-2022 + needs: [build] + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + + - name: Set configuration env + shell: pwsh + run: | + if ($env:GITHUB_REF -eq 'refs/heads/release') { + echo 'CONFIGURATION=Release' >> $env:GITHUB_ENV + } else { + echo 'CONFIGURATION=Debug' >> $env:GITHUB_ENV + } + + - uses: actions/cache@v3 + with: + path: ${{ github.workspace }}/.nuget/packages + key: nuget-${{ hashFiles('*/*.csproj') }} + restore-keys: | + nuget- + + - name: Restore build result + uses: actions/download-artifact@v3 + with: + name: build + + - name: Run tests + shell: pwsh + run: | + $altCoverVersion = '8.2.837' + $xunitVersion = '2.4.1' + $targetFramework = 'net472' + $altCoverPath = "$($env:NUGET_PACKAGES)\altcover\$($altCoverVersion)\tools\$($targetFramework)\AltCover.exe" + $xunitPath = "$($env:NUGET_PACKAGES)\xunit.runner.console\$($xunitVersion)\tools\$($targetFramework)\xunit.console.exe" + + Start-Process ` + -FilePath $altCoverPath ` + -ArgumentList ( + '--inputDirectory', + ".\OpenTween.Tests\bin\$($env:CONFIGURATION)\$($targetFramework)", + '--outputDirectory', + '.\__Instrumented\', + '--assemblyFilter', + '?^OpenTween(?!\.Tests)', + '--typeFilter', + '?^OpenTween\.', + '--fileFilter', + '\.Designer\.cs', + '--visibleBranches' + ) ` + -NoNewWindow ` + -Wait + + Start-Process ` + -FilePath $altCoverPath ` + -ArgumentList ( + 'runner', + '--recorderDirectory', + '.\__Instrumented\', + '--executable', + $xunitPath, + '--', + '.\__Instrumented\OpenTween.Tests.dll' + ) ` + -NoNewWindow ` + -Wait + + - name: Upload test results to codecov + shell: pwsh + run: | + Invoke-WebRequest -Uri https://uploader.codecov.io/latest/windows/codecov.exe -Outfile codecov.exe + .\codecov.exe -f coverage.xml + + package: + runs-on: windows-2022 + needs: [build] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: '${{ github.event.pull_request.head.sha }}' + + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.1 + + - name: Set configuration env + shell: pwsh + run: | + if ($env:GITHUB_REF -eq 'refs/heads/release') { + echo 'CONFIGURATION=Release' >> $env:GITHUB_ENV + } else { + echo 'CONFIGURATION=Debug' >> $env:GITHUB_ENV + } + + - name: Restore build result + uses: actions/download-artifact@v3 + with: + name: build + + - name: Build package + shell: powershell # runtime-versionを取得するため従来のPowershellを使用する + run: | + $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Msbuild\Current\Bin\Roslyn\' + $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\' + $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\' + $assemblyInfo = '.\OpenTween\Properties\AssemblyInfo.cs' + $destPath = 'OpenTween.zip' + $headCommit = '${{ github.event.pull_request.head.sha }}' + .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -AssemblyInfo $assemblyInfo -DestPath $destPath -HeadCommit $headCommit + Copy-Item ($binDir + 'OpenTween.pdb') -Destination '.\' + + - name: Upload build result + uses: actions/upload-artifact@v3 + with: + name: package + path: | + ./OpenTween.zip + ./OpenTween.pdb From f9a2005499cf20434fd150884516023f9b1eed31 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Wed, 10 Aug 2022 15:28:27 +0900 Subject: [PATCH 244/402] =?UTF-8?q?OpenTween.csproj=E3=82=92=E6=96=B0?= =?UTF-8?q?=E3=81=97=E3=81=84=E5=BD=A2=E5=BC=8F=E3=81=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 4 +- OpenTween/OpenTween.csproj | 526 ++++++++++----------------- OpenTween/Properties/AssemblyInfo.cs | 28 -- appveyor.yml | 4 +- 4 files changed, 187 insertions(+), 375 deletions(-) delete mode 100644 OpenTween/Properties/AssemblyInfo.cs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4816cdbc6..4a16fc91b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -157,8 +157,8 @@ jobs: shell: powershell # runtime-versionを取得するため従来のPowershellを使用する run: | $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Msbuild\Current\Bin\Roslyn\' - $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\' - $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\' + $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\net472\' + $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\net472\' $assemblyInfo = '.\OpenTween\Properties\AssemblyInfo.cs' $destPath = 'OpenTween.zip' $headCommit = '${{ github.event.pull_request.head.sha }}' diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 626f553fc..13efdb7d4 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -1,41 +1,26 @@ - - - + - Debug - AnyCPU - {3D8995C7-BDF3-4273-9F9D-DDD902F6A101} WinExe - OpenTween - OpenTween - v4.7.2 + net472 10.0 - 512 + OpenTween (dev) + 2.7.1.1 + Client of Twitter. Free software(GPLv3) + (C) 2011 OpenTween contributors + bin\$(Configuration)\ true + true $(MSBuildProjectDirectory)=. - true portable - false - bin\Debug\ - TRACE;DEBUG - prompt - 4 Off - false OpenTween.ruleset portable - true - bin\Release\ - TRACE - prompt - 4 Off false - false OpenTween.ApplicationEvents @@ -62,667 +47,526 @@ - + Form - + ApiInfoDialog.cs - - - - - - - - - - - - - + Code - - - - - - - - - - - - - - - - - - - - - - + Code - - - - - - - - + Form - + AtIdSupplement.cs - + Form - + AppendSettingDialog.cs - + Form - + AuthDialog.cs - - - - - - - - - - - - - - - - - - - + Form - + EncryptApiKeyDialog.cs - - + Form - + FilterDialog.cs - - + Form - + LoginDialog.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - + Form - + SendErrorReportForm.cs - - - - - - - - - + UserControl - + TweetDetailsView.cs - - + Form - + WaitingDialog.cs - + Form - + InputDialog.cs - + UserControl - + MediaSelector.cs - + Code - + Form - + Component - - + Form - + HashtagManage.cs - - + Form - + ListAvailable.cs - - Form - - + + ListManage.cs - - + Component - - - + Component - - + UserControl - + ActionPanel.cs - + UserControl - + BasedPanel.cs - + UserControl - + ConnectionPanel.cs - + UserControl - + CooperatePanel.cs - + UserControl - + FontPanel.cs - + UserControl - + FontPanel2.cs - + UserControl - + GetCountPanel.cs - + UserControl - + GetPeriodPanel.cs - + UserControl - + NotifyPanel.cs - + UserControl - + PreviewPanel.cs - + UserControl - + ProxyPanel.cs - + UserControl - + SettingPanelBase.cs - + UserControl - + ShortUrlPanel.cs - + UserControl - + StartupPanel.cs - + UserControl - + TweetActPanel.cs - + UserControl - + TweetPrvPanel.cs - - + Form - + TabsDialog.cs - - - - - - - - - - - - - - - - - + UserControl - + TweetThumbnail.cs - + Form - + UpdateDialog.cs - - - + Form - + InputTabName.cs - - - - - - + Form - + MyLists.cs - - + Form - + OpenURL.cs - - + True True Resources.resx - + Form - + SearchWordDialog.cs - - - - - - - + Form - + UserInfoDialog.cs - + Component - + Form - + Tween.cs - + Form - + TweenAboutBox.cs - + Component - - - - - - - + ApiInfoDialog.cs - + AuthDialog.cs - + AuthDialog.cs - + EncryptApiKeyDialog.cs - + FilterDialog.cs - + FilterDialog.cs - + HashtagManage.cs - + HashtagManage.cs - + InputDialog.cs - + InputDialog.cs - + ListAvailable.cs - + ListAvailable.cs - + ListManage.cs - + ListManage.cs - + AtIdSupplement.cs - + AtIdSupplement.cs - + AppendSettingDialog.cs Designer - + AppendSettingDialog.cs Designer - + LoginDialog.cs - + LoginDialog.cs - + MediaSelector.cs - + MediaSelector.cs - + SendErrorReportForm.cs - + SendErrorReportForm.cs - + TweetDetailsView.cs Designer - + TweetDetailsView.cs - + WaitingDialog.cs - + ActionPanel.cs - + ActionPanel.cs - + BasedPanel.cs - + BasedPanel.cs - + ConnectionPanel.cs - + ConnectionPanel.cs - + CooperatePanel.cs - + CooperatePanel.cs - + FontPanel.cs - + FontPanel.cs - + FontPanel2.cs - + FontPanel2.cs - + GetCountPanel.cs - + GetCountPanel.cs - + GetPeriodPanel.cs - + GetPeriodPanel.cs - + NotifyPanel.cs - + NotifyPanel.cs - + PreviewPanel.cs - + PreviewPanel.cs - + ProxyPanel.cs - + ProxyPanel.cs - + ShortUrlPanel.cs - + ShortUrlPanel.cs - + StartupPanel.cs - + StartupPanel.cs - + TweetActPanel.cs - + TweetActPanel.cs - + TweetPrvPanel.cs - + TweetPrvPanel.cs - + TabsDialog.cs - + TabsDialog.cs - + TweetThumbnail.cs - + TweetThumbnail.cs - + UpdateDialog.cs - + UpdateDialog.cs - + InputTabName.cs - + InputTabName.cs - + MyLists.cs - + MyLists.cs - + OpenURL.cs - + OpenURL.cs - + ResXFileCodeGenerator Resources.Designer.cs Designer - + Designer - + SearchWordDialog.cs - + SearchWordDialog.cs - + UserInfoDialog.cs - + UserInfoDialog.cs - + Tween.cs Designer - + Tween.cs Designer - + TweenAboutBox.cs - + TweenAboutBox.cs @@ -800,14 +644,10 @@ all - - + + + + diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs deleted file mode 100644 index 4b29abd38..000000000 --- a/OpenTween/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 -// アセンブリに関連付けられている情報を変更するには、 -// これらの属性値を変更してください。 -[assembly: AssemblyTitle("OpenTween (dev)")] -[assembly: AssemblyDescription("Client of Twitter. Free software(GPLv3)")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("OpenTween (dev)")] -[assembly: AssemblyCopyright("(C) 2011 OpenTween contributors")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから -// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 -// その型の ComVisible 属性を true に設定してください。 -[assembly: ComVisible(false)] - -// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です -[assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] - -[assembly: AssemblyVersion("2.7.1.1")] - -[assembly: InternalsVisibleTo("OpenTween.Tests")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq diff --git a/appveyor.yml b/appveyor.yml index f13edc956..88470c42d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -79,8 +79,8 @@ after_test: .\codecov.exe -f coverage.xml - ps: | $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\Roslyn\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\' - $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\' - $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\' + $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\net472\' + $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\net472\' $assemblyInfo = '.\OpenTween\Properties\AssemblyInfo.cs' if ($env:RELEASE_TAG -eq 'true') { $destPath = $env:APPVEYOR_REPO_TAG_NAME + '.zip' From 4dad89ad5fbaaf6a57fe53a48faf71d4b9b12748 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Thu, 11 Aug 2022 00:00:35 +0900 Subject: [PATCH 245/402] =?UTF-8?q?=E3=83=93=E3=83=AB=E3=83=89=E3=82=B9?= =?UTF-8?q?=E3=82=AF=E3=83=AA=E3=83=97=E3=83=88=E3=82=92=E6=96=B0=E3=81=97?= =?UTF-8?q?=E3=81=84=E5=BD=A2=E5=BC=8F=E3=81=AEcsproj=E3=81=AB=E5=AF=BE?= =?UTF-8?q?=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 3 +-- appveyor.yml | 3 +-- tools/build-satelite-assembly.ps1 | 3 +-- tools/build-zip-archive.ps1 | 5 ++--- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4a16fc91b..c69ebd06c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -159,10 +159,9 @@ jobs: $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Msbuild\Current\Bin\Roslyn\' $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\net472\' $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\net472\' - $assemblyInfo = '.\OpenTween\Properties\AssemblyInfo.cs' $destPath = 'OpenTween.zip' $headCommit = '${{ github.event.pull_request.head.sha }}' - .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -AssemblyInfo $assemblyInfo -DestPath $destPath -HeadCommit $headCommit + .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -DestPath $destPath -HeadCommit $headCommit Copy-Item ($binDir + 'OpenTween.pdb') -Destination '.\' - name: Upload build result diff --git a/appveyor.yml b/appveyor.yml index 88470c42d..096c3fe9f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -81,7 +81,6 @@ after_test: $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\Roslyn\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\' $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\net472\' $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\net472\' - $assemblyInfo = '.\OpenTween\Properties\AssemblyInfo.cs' if ($env:RELEASE_TAG -eq 'true') { $destPath = $env:APPVEYOR_REPO_TAG_NAME + '.zip' } else { @@ -92,7 +91,7 @@ after_test: } else { $headCommit = 'HEAD' } - .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -AssemblyInfo $assemblyInfo -DestPath $destPath -HeadCommit $headCommit + .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -DestPath $destPath -HeadCommit $headCommit Copy-Item ($binDir + 'OpenTween.pdb') -Destination '.\' # vim: et fenc=utf-8 sts=2 sw=2 ts=2 diff --git a/tools/build-satelite-assembly.ps1 b/tools/build-satelite-assembly.ps1 index d47bb37a1..744a4b7f0 100644 --- a/tools/build-satelite-assembly.ps1 +++ b/tools/build-satelite-assembly.ps1 @@ -29,7 +29,6 @@ Param( [Parameter(Mandatory = $true)][String] $ObjDir, [Parameter(Mandatory = $true)][String] $Culture, - [Parameter(Mandatory = $true)][String] $AssemblyInfo, [Parameter(Mandatory = $true)][String] $DestPath ) @@ -40,7 +39,7 @@ $ErrorActionPreference = 'Stop' Function Generate-AssemblyInfo() { $tmpFile = New-TemporaryFile - $content = (Get-Content $AssemblyInfo) -replace "^\[assembly: AssemblyCulture.+$", "[assembly: AssemblyCulture(`"${Culture}`")]" + $content = "[assembly: System.Reflection.AssemblyCulture(`"${Culture}`")]" $content > $tmpFile.FullName return $tmpFile.FullName } diff --git a/tools/build-zip-archive.ps1 b/tools/build-zip-archive.ps1 index 804e1e509..8a5421363 100644 --- a/tools/build-zip-archive.ps1 +++ b/tools/build-zip-archive.ps1 @@ -23,13 +23,12 @@ # Reproducible Build に対応した ZIP アーカイブのビルドを行うスクリプト # # 使い方: -# .\tools\build-zip-archive.ps1 -BinDir .\OpenTween\bin\Debug\ -ObjDir .\OpenTween\obj\Debug\ -AssemblyInfo .\OpenTween\Properties\AssemblyInfo.cs -DestPath OpenTween.zip +# .\tools\build-zip-archive.ps1 -BinDir .\OpenTween\bin\Debug\ -ObjDir .\OpenTween\obj\Debug\ -DestPath OpenTween.zip # Param( [Parameter(Mandatory = $true)][String] $BinDir, [Parameter(Mandatory = $true)][String] $ObjDir, - [Parameter(Mandatory = $true)][String] $AssemblyInfo, [Parameter(Mandatory = $true)][String] $DestPath, [String] $HeadCommit = 'HEAD' ) @@ -57,7 +56,7 @@ $includeFiles = @( Function Build-SateliteAssembly([String] $Culture) { # OpenTween.resources.dll の生成(カルチャ別) $sateliteAssemblyPath = Join-Path $BinDir "${Culture}\${assemblyName}.resources.dll" - .\tools\build-satelite-assembly.ps1 -ObjDir $ObjDir -Culture $Culture -DestPath $sateliteAssemblyPath -AssemblyInfo $AssemblyInfo + .\tools\build-satelite-assembly.ps1 -ObjDir $ObjDir -Culture $Culture -DestPath $sateliteAssemblyPath } Function Get-SourceDateEpoch() { From 9d2e9b82014cba888743e11f09daddc7d31ce1a9 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Fri, 12 Aug 2022 22:05:05 +0900 Subject: [PATCH 246/402] =?UTF-8?q?Microsoft.NET.Sdk=20=E3=81=A7=E3=81=AF?= =?UTF-8?q?=E3=83=87=E3=83=95=E3=82=A9=E3=83=AB=E3=83=88=E3=81=A7=20Determ?= =?UTF-8?q?inistic=3Dtrue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/OpenTween.csproj | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 13efdb7d4..5e4657288 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -8,8 +8,7 @@ Client of Twitter. Free software(GPLv3) (C) 2011 OpenTween contributors bin\$(Configuration)\ - true - true + true $(MSBuildProjectDirectory)=. From d94f5862408e848355f497edf211aac864c61b94 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Fri, 2 Sep 2022 23:45:29 +0900 Subject: [PATCH 247/402] Add UseWindowsForms --- OpenTween/OpenTween.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 5e4657288..364776167 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -1,6 +1,7 @@  WinExe + true net472 10.0 OpenTween (dev) From 50c3685005d97ab72cb5c38fe5731419b655d900 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Sat, 1 Oct 2022 10:34:46 +0900 Subject: [PATCH 248/402] =?UTF-8?q?GenerateSatelliteAssembliesForCore=20?= =?UTF-8?q?=E3=82=92=E6=9C=89=E5=8A=B9=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 従来はサテライトアセンブリを生成する際に deterministic オプションを有効にする ために build-satelite-assembly.ps1 で独自に csc.exe を呼び出していたが、 csproj の設定で GenerateSatelliteAssembliesForCore を有効にすることで同等の 効果を得ることができたためこれに置き換えた https://learn.microsoft.com/en-us/dotnet/core/extensions/create-satellite-assemblies#compile-satellite-assemblies --- .github/workflows/build.yml | 3 +- OpenTween/OpenTween.csproj | 1 + appveyor.yml | 3 +- tools/build-satelite-assembly.ps1 | 59 ------------------------------- tools/build-zip-archive.ps1 | 11 +----- 5 files changed, 4 insertions(+), 73 deletions(-) delete mode 100644 tools/build-satelite-assembly.ps1 diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c69ebd06c..a7de4ede0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -158,10 +158,9 @@ jobs: run: | $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Msbuild\Current\Bin\Roslyn\' $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\net472\' - $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\net472\' $destPath = 'OpenTween.zip' $headCommit = '${{ github.event.pull_request.head.sha }}' - .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -DestPath $destPath -HeadCommit $headCommit + .\tools\build-zip-archive.ps1 -BinDir $binDir -DestPath $destPath -HeadCommit $headCommit Copy-Item ($binDir + 'OpenTween.pdb') -Destination '.\' - name: Upload build result diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 364776167..8002c131b 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -10,6 +10,7 @@ (C) 2011 OpenTween contributors bin\$(Configuration)\ true + true $(MSBuildProjectDirectory)=. diff --git a/appveyor.yml b/appveyor.yml index 096c3fe9f..970720669 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -80,7 +80,6 @@ after_test: - ps: | $env:PATH = $env:PATH + ';C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\Roslyn\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\' $binDir = '.\OpenTween\bin\' + $env:CONFIGURATION + '\net472\' - $objDir = '.\OpenTween\obj\' + $env:CONFIGURATION + '\net472\' if ($env:RELEASE_TAG -eq 'true') { $destPath = $env:APPVEYOR_REPO_TAG_NAME + '.zip' } else { @@ -91,7 +90,7 @@ after_test: } else { $headCommit = 'HEAD' } - .\tools\build-zip-archive.ps1 -BinDir $binDir -ObjDir $objDir -DestPath $destPath -HeadCommit $headCommit + .\tools\build-zip-archive.ps1 -BinDir $binDir -DestPath $destPath -HeadCommit $headCommit Copy-Item ($binDir + 'OpenTween.pdb') -Destination '.\' # vim: et fenc=utf-8 sts=2 sw=2 ts=2 diff --git a/tools/build-satelite-assembly.ps1 b/tools/build-satelite-assembly.ps1 deleted file mode 100644 index 744a4b7f0..000000000 --- a/tools/build-satelite-assembly.ps1 +++ /dev/null @@ -1,59 +0,0 @@ -# OpenTween - Client of Twitter -# Copyright (c) 2021 kim_upsilon (@kim_upsilon) -# All rights reserved. -# -# This file is part of OpenTween. -# -# This program is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by the Free -# Software Foundation; either version 3 of the License, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program. If not, see , or write to -# the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, -# Boston, MA 02110-1301, USA. - -# -# Reproducible Build に対応したサテライトアセンブリのビルド -# -# 使い方: -# .\tools\build-satelite-assembly.ps1 -ObjDir .\OpenTween\obj\Debug\ -Culture en -AssemblyInfo .\OpenTween\Properties\AssemblyInfo.cs -DestPath .\OpenTween\bin\Debug\en\OpenTween.resources.dll -# - -Param( - [Parameter(Mandatory = $true)][String] $ObjDir, - [Parameter(Mandatory = $true)][String] $Culture, - [Parameter(Mandatory = $true)][String] $DestPath -) - -Set-StrictMode -Version 3.0 -$ErrorActionPreference = 'Stop' - -. .\tools\functions.ps1 - -Function Generate-AssemblyInfo() { - $tmpFile = New-TemporaryFile - $content = "[assembly: System.Reflection.AssemblyCulture(`"${Culture}`")]" - $content > $tmpFile.FullName - return $tmpFile.FullName -} - -Function Build-SateliteAssembly() { - $tmpAssemblyInfoPath = Generate-AssemblyInfo - try { - $resourcePaths = Get-ChildItem -Path $ObjDir -File -Filter "*.${Culture}.resources" - $cscOpts = "-utf8output -nologo -deterministic -target:library -debug- -optimize+ -out:${DestPath}" - $cscOpts += " " + ($resourcePaths | % { "-resource:$($_.FullName)" }) -join ' ' - Invoke-NativeCommand "csc $cscOpts $tmpAssemblyInfoPath" - } finally { - Remove-Item -Path $tmpAssemblyInfoPath - } -} - -Build-SateliteAssembly diff --git a/tools/build-zip-archive.ps1 b/tools/build-zip-archive.ps1 index 8a5421363..3fd8f5989 100644 --- a/tools/build-zip-archive.ps1 +++ b/tools/build-zip-archive.ps1 @@ -23,12 +23,11 @@ # Reproducible Build に対応した ZIP アーカイブのビルドを行うスクリプト # # 使い方: -# .\tools\build-zip-archive.ps1 -BinDir .\OpenTween\bin\Debug\ -ObjDir .\OpenTween\obj\Debug\ -DestPath OpenTween.zip +# .\tools\build-zip-archive.ps1 -BinDir .\OpenTween\bin\Debug\ -DestPath OpenTween.zip # Param( [Parameter(Mandatory = $true)][String] $BinDir, - [Parameter(Mandatory = $true)][String] $ObjDir, [Parameter(Mandatory = $true)][String] $DestPath, [String] $HeadCommit = 'HEAD' ) @@ -53,12 +52,6 @@ $includeFiles = @( . .\tools\functions.ps1 -Function Build-SateliteAssembly([String] $Culture) { - # OpenTween.resources.dll の生成(カルチャ別) - $sateliteAssemblyPath = Join-Path $BinDir "${Culture}\${assemblyName}.resources.dll" - .\tools\build-satelite-assembly.ps1 -ObjDir $ObjDir -Culture $Culture -DestPath $sateliteAssemblyPath -} - Function Get-SourceDateEpoch() { # 本来 $unixEpoch は UTC で表さなければならないが、ZIP アーカイブには # ローカルのタイムゾーンの日時でタイムスタンプが記録されるため、わざとタイムゾーンを指定していない。 @@ -92,8 +85,6 @@ Function Get-RuntimeVersion() { } } -Build-SateliteAssembly -Culture en - $includePaths = $includeFiles | % { Join-Path $BinDir $_ } $timestamp = Get-SourceDateEpoch From 21c17cef4f3f2ba990ea0169fefc32ddae362dcd Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 00:38:18 +0900 Subject: [PATCH 249/402] =?UTF-8?q?AssemblyInfo.cs=20=E3=81=AE=E8=87=AA?= =?UTF-8?q?=E5=8B=95=E7=94=9F=E6=88=90=E3=82=92=E7=84=A1=E5=8A=B9=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 生成されるソースコードに含まれるコメントがロケール設定に依存して変化してしまい Reproducible build の妨げとなる問題があるため、回避策が見つかるまで無効化する。 --- OpenTween/OpenTween.csproj | 5 +---- OpenTween/Properties/AssemblyInfo.cs | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 OpenTween/Properties/AssemblyInfo.cs diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 8002c131b..414945b28 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -4,12 +4,9 @@ true net472 10.0 - OpenTween (dev) - 2.7.1.1 - Client of Twitter. Free software(GPLv3) - (C) 2011 OpenTween contributors bin\$(Configuration)\ true + false true $(MSBuildProjectDirectory)=. diff --git a/OpenTween/Properties/AssemblyInfo.cs b/OpenTween/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..4b29abd38 --- /dev/null +++ b/OpenTween/Properties/AssemblyInfo.cs @@ -0,0 +1,28 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle("OpenTween (dev)")] +[assembly: AssemblyDescription("Client of Twitter. Free software(GPLv3)")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("OpenTween (dev)")] +[assembly: AssemblyCopyright("(C) 2011 OpenTween contributors")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible(false)] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid("2d0ae0ba-adac-49a2-9b10-26fd69e695bf")] + +[assembly: AssemblyVersion("2.7.1.1")] + +[assembly: InternalsVisibleTo("OpenTween.Tests")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq From f2438cee64fac8d615585608ba02e4e5d091d37f Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 02:22:18 +0900 Subject: [PATCH 250/402] =?UTF-8?q?ImageCache=E3=81=AB=E5=AF=BE=E3=81=99?= =?UTF-8?q?=E3=82=8B=E6=93=8D=E4=BD=9C=E5=85=83=E3=82=92UI=E3=82=B9?= =?UTF-8?q?=E3=83=AC=E3=83=83=E3=83=89=E3=81=AE=E3=81=BF=E3=81=AB=E3=81=99?= =?UTF-8?q?=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WM_PAINT 内で Mutex を使用することによる問題を回避するため、ImageCache を UI スレッド以外から操作しないことで Mutex が不要な設計に変更する。 --- OpenTween/ImageCache.cs | 64 ++++++++----------------- OpenTween/TimelineListViewDrawer.cs | 74 ++++++++++++++++------------- 2 files changed, 62 insertions(+), 76 deletions(-) diff --git a/OpenTween/ImageCache.cs b/OpenTween/ImageCache.cs index 76bfb639e..335c49c12 100644 --- a/OpenTween/ImageCache.cs +++ b/OpenTween/ImageCache.cs @@ -46,11 +46,6 @@ public class ImageCache : IDisposable /// private CancellationTokenSource cancelTokenSource; - /// - /// innerDictionary の排他制御のためのロックオブジェクト - /// - private readonly object lockObject = new(); - /// /// オブジェクトが破棄された否か /// @@ -89,25 +84,17 @@ public Task DownloadImageAsync(string address, bool force = false) { var cancelToken = this.cancelTokenSource.Token; - return Task.Run(() => - { - Task? cachedImageTask; - lock (this.lockObject) - this.InnerDictionary.TryGetValue(address, out cachedImageTask); - - if (cachedImageTask != null && !force) - return cachedImageTask; + this.InnerDictionary.TryGetValue(address, out var cachedImageTask); - cancelToken.ThrowIfCancellationRequested(); + if (cachedImageTask != null && !force) + return cachedImageTask; - var imageTask = this.FetchImageAsync(address, cancelToken); + cancelToken.ThrowIfCancellationRequested(); - lock (this.lockObject) - this.InnerDictionary[address] = imageTask; + var imageTask = Task.Run(() => this.FetchImageAsync(address, cancelToken)); + this.InnerDictionary[address] = imageTask; - return imageTask; - }, - cancelToken); + return imageTask; } private async Task FetchImageAsync(string uri, CancellationToken cancelToken) @@ -126,14 +113,11 @@ private async Task FetchImageAsync(string uri, CancellationToken ca public MemoryImage? TryGetFromCache(string address) { - lock (this.lockObject) - { - if (!this.InnerDictionary.TryGetValue(address, out var imageTask) || - imageTask.Status != TaskStatus.RanToCompletion) - return null; + if (!this.InnerDictionary.TryGetValue(address, out var imageTask) || + imageTask.Status != TaskStatus.RanToCompletion) + return null; - return imageTask.Result; - } + return imageTask.Result; } public MemoryImage? TryGetLargerOrSameSizeFromCache(string normalUrl, string size) @@ -154,14 +138,11 @@ private async Task FetchImageAsync(string uri, CancellationToken ca public void CancelAsync() { - lock (this.lockObject) - { - var oldTokenSource = this.cancelTokenSource; - this.cancelTokenSource = new CancellationTokenSource(); + var oldTokenSource = this.cancelTokenSource; + this.cancelTokenSource = new CancellationTokenSource(); - oldTokenSource.Cancel(); - oldTokenSource.Dispose(); - } + oldTokenSource.Cancel(); + oldTokenSource.Dispose(); } protected virtual void Dispose(bool disposing) @@ -172,17 +153,14 @@ protected virtual void Dispose(bool disposing) { this.CancelAsync(); - lock (this.lockObject) + foreach (var (_, task) in this.InnerDictionary) { - foreach (var (_, task) in this.InnerDictionary) - { - if (task.Status == TaskStatus.RanToCompletion) - task.Result?.Dispose(); - } - - this.InnerDictionary.Clear(); - this.cancelTokenSource.Dispose(); + if (task.Status == TaskStatus.RanToCompletion) + task.Result?.Dispose(); } + + this.InnerDictionary.Clear(); + this.cancelTokenSource.Dispose(); } this.disposed = true; diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs index 1e2ae355f..44bcb9adc 100644 --- a/OpenTween/TimelineListViewDrawer.cs +++ b/OpenTween/TimelineListViewDrawer.cs @@ -167,6 +167,9 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) if (stateRect.Width > 0) e.Graphics.DrawIcon(this.GetPostStateIcon(post.StateIndex), stateRect); } + + // キャッシュにない画像の場合は読み込みが完了してから再描画する + _ = this.LoadProfileImage(post, scaledIconSize.Width); } private MemoryImage? LoadListViewIconLazy(PostClass post, int scaledIconSize) @@ -183,43 +186,48 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) if (cachedImage != null) return cachedImage; - // キャッシュにない画像の場合は読み込みが完了してから再描画する - _ = Task.Run(async () => - { - try - { - var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); - await this.iconCache.DownloadImageAsync(imageUrl); - } - catch (InvalidImageException) - { - return; - } - catch (HttpRequestException) - { - return; - } - catch (OperationCanceledException) - { - return; - } + return null; + } - await this.parentForm.InvokeAsync(() => - { - if (this.listView.IsDisposed) - return; + private async Task LoadProfileImage(PostClass post, int scaledIconSize) + { + if (scaledIconSize <= 0) + return; - if (this.listView.VirtualListSize == 0) - return; + var normalImageUrl = post.ImageUrl; + if (MyCommon.IsNullOrEmpty(normalImageUrl)) + return; - // ロード中に index の指す行が変化している可能性がある - var newIndex = this.tab.IndexOf(post.StatusId); - if (newIndex != -1) - this.listView.RedrawItems(newIndex, newIndex, true); - }); - }); + var sizeName = Twitter.DecideProfileImageSize(scaledIconSize); - return null; + try + { + var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); + await this.iconCache.DownloadImageAsync(imageUrl); + } + catch (InvalidImageException) + { + return; + } + catch (HttpRequestException) + { + return; + } + catch (OperationCanceledException) + { + return; + } + + if (this.listView.IsDisposed) + return; + + if (this.listView.VirtualListSize == 0) + return; + + // ロード中に index の指す行が変化している可能性がある + var newIndex = this.tab.IndexOf(post.StatusId); + if (newIndex != -1) + this.listView.RedrawItems(newIndex, newIndex, true); } private Icon GetPostStateIcon(int stateIndex) From 3cd3775b308e29363f795d49c008f59f1d2d0341 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 03:16:13 +0900 Subject: [PATCH 251/402] =?UTF-8?q?DrawListViewItemIcon=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=81=8B=E3=82=89=E3=83=97=E3=83=AD=E3=83=95?= =?UTF-8?q?=E3=82=A3=E3=83=BC=E3=83=AB=E7=94=BB=E5=83=8F=E3=81=AE=E6=8F=8F?= =?UTF-8?q?=E7=94=BB=E5=87=A6=E7=90=86=E3=82=92=E3=83=A1=E3=82=BD=E3=83=83?= =?UTF-8?q?=E3=83=89=E3=81=AB=E6=8A=BD=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/TimelineListViewDrawer.cs | 81 ++++++++++++++--------------- 1 file changed, 38 insertions(+), 43 deletions(-) diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs index 44bcb9adc..2d8bdf4ae 100644 --- a/OpenTween/TimelineListViewDrawer.cs +++ b/OpenTween/TimelineListViewDrawer.cs @@ -147,19 +147,7 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) iconRect.Offset(0, Math.Max(0, (itemRect.Height - scaledIconSize.Height) / 2)); var post = this.tab[item.Index]; - var img = this.LoadListViewIconLazy(post, scaledIconSize.Width); - if (img != null) - { - e.Graphics.FillRectangle(Brushes.White, iconRect); - e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; - try - { - e.Graphics.DrawImage(img.Image, iconRect); - } - catch (ArgumentException) - { - } - } + this.DrawListViewItemProfileImage(e.Graphics, post, scaledIconSize, iconRect); if (post.StateIndex > -1) { @@ -167,39 +155,57 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) if (stateRect.Width > 0) e.Graphics.DrawIcon(this.GetPostStateIcon(post.StateIndex), stateRect); } - - // キャッシュにない画像の場合は読み込みが完了してから再描画する - _ = this.LoadProfileImage(post, scaledIconSize.Width); } - private MemoryImage? LoadListViewIconLazy(PostClass post, int scaledIconSize) + private void DrawListViewItemProfileImage(Graphics g, PostClass post, Size scaledIconSize, Rectangle iconRect) { - if (scaledIconSize <= 0) - return null; + if (scaledIconSize.Width <= 0) + return; var normalImageUrl = post.ImageUrl; if (MyCommon.IsNullOrEmpty(normalImageUrl)) - return null; + return; - var sizeName = Twitter.DecideProfileImageSize(scaledIconSize); + var sizeName = Twitter.DecideProfileImageSize(scaledIconSize.Width); var cachedImage = this.iconCache.TryGetLargerOrSameSizeFromCache(normalImageUrl, sizeName); + if (cachedImage != null) - return cachedImage; + { + g.FillRectangle(Brushes.White, iconRect); + g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; + try + { + g.DrawImage(cachedImage.Image, iconRect); + } + catch (ArgumentException) + { + } + } + else + { + // キャッシュにない画像の場合は読み込みが完了してから再描画する + async Task RefreshProfileImageLazy() + { + await this.LoadProfileImage(normalImageUrl, sizeName); - return null; - } + if (this.listView.IsDisposed) + return; - private async Task LoadProfileImage(PostClass post, int scaledIconSize) - { - if (scaledIconSize <= 0) - return; + if (this.listView.VirtualListSize == 0) + return; - var normalImageUrl = post.ImageUrl; - if (MyCommon.IsNullOrEmpty(normalImageUrl)) - return; + // ロード中に index の指す行が変化している可能性がある + var newIndex = this.tab.IndexOf(post.StatusId); + if (newIndex != -1) + this.listView.RedrawItems(newIndex, newIndex, true); + } - var sizeName = Twitter.DecideProfileImageSize(scaledIconSize); + _ = RefreshProfileImageLazy(); + } + } + private async Task LoadProfileImage(string normalImageUrl, string sizeName) + { try { var imageUrl = Twitter.CreateProfileImageUrl(normalImageUrl, sizeName); @@ -217,17 +223,6 @@ private async Task LoadProfileImage(PostClass post, int scaledIconSize) { return; } - - if (this.listView.IsDisposed) - return; - - if (this.listView.VirtualListSize == 0) - return; - - // ロード中に index の指す行が変化している可能性がある - var newIndex = this.tab.IndexOf(post.StatusId); - if (newIndex != -1) - this.listView.RedrawItems(newIndex, newIndex, true); } private Icon GetPostStateIcon(int stateIndex) From e137069be02edaa4ae586ae933c9475f3ea03734 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 03:16:48 +0900 Subject: [PATCH 252/402] =?UTF-8?q?DrawListViewItemIcon=E3=81=8B=E3=82=89S?= =?UTF-8?q?tateIcon=E3=81=AE=E6=8F=8F=E7=94=BB=E5=87=A6=E7=90=86=E3=82=92?= =?UTF-8?q?=E3=83=A1=E3=82=BD=E3=83=83=E3=83=89=E3=81=AB=E6=8A=BD=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/TimelineListViewDrawer.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/OpenTween/TimelineListViewDrawer.cs b/OpenTween/TimelineListViewDrawer.cs index 2d8bdf4ae..02b82be57 100644 --- a/OpenTween/TimelineListViewDrawer.cs +++ b/OpenTween/TimelineListViewDrawer.cs @@ -149,12 +149,19 @@ private void DrawListViewItemIcon(DrawListViewItemEventArgs e) var post = this.tab[item.Index]; this.DrawListViewItemProfileImage(e.Graphics, post, scaledIconSize, iconRect); - if (post.StateIndex > -1) - { - var stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + scaledIconSize.Width + 2, iconRect.Y), scaledStateSize), itemRect); - if (stateRect.Width > 0) - e.Graphics.DrawIcon(this.GetPostStateIcon(post.StateIndex), stateRect); - } + var stateRect = Rectangle.Intersect(new Rectangle(new Point(iconRect.X + scaledIconSize.Width + 2, iconRect.Y), scaledStateSize), itemRect); + this.DrawListViewItemStateIcon(e.Graphics, post, stateRect); + } + + private void DrawListViewItemStateIcon(Graphics g, PostClass post, Rectangle stateRect) + { + if (post.StateIndex == -1) + return; + + if (stateRect.Width <= 0) + return; + + g.DrawIcon(this.GetPostStateIcon(post.StateIndex), stateRect); } private void DrawListViewItemProfileImage(Graphics g, PostClass post, Size scaledIconSize, Rectangle iconRect) From 2dd20ca449c3f52b777e72df8abd703ad22233ef Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 03:37:50 +0900 Subject: [PATCH 253/402] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AB=E3=81=AA?= =?UTF-8?q?=E3=81=A3=E3=81=9F=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 17 -------- .tx/config | 99 --------------------------------------------- packages/.gitignore | 1 - 3 files changed, 117 deletions(-) delete mode 100644 .travis.yml delete mode 100644 .tx/config delete mode 100644 packages/.gitignore diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 149d75c3f..000000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: csharp -solution: OpenTween.sln - -sudo: false - -cache: - directories: - - ./packages/ - -before_script: - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - -script: - - nuget restore -PackagesDirectory packages - - msbuild /p:Configuration=Debug /verbosity:quiet - - mono ./packages/xunit.runner.console/2.3.1/tools/net452/xunit.console.exe ./OpenTween.Tests/bin/Debug/net472/OpenTween.Tests.dll -appdomains denied -parallel none diff --git a/.tx/config b/.tx/config deleted file mode 100644 index c0c8599df..000000000 --- a/.tx/config +++ /dev/null @@ -1,99 +0,0 @@ -[main] -host = https://www.transifex.com -type = RESX - -[opentween.global] -file_filter = OpenTween/Properties/Resources..resx -source_file = OpenTween/Properties/Resources.resx -source_lang = ja - -[opentween.AppendSettingDialog] -file_filter = OpenTween/AppendSettingDialog..resx -source_file = OpenTween/AppendSettingDialog.resx -source_lang = ja - -[opentween.AtIdSupplement] -file_filter = OpenTween/AtIdSupplement..resx -source_file = OpenTween/AtIdSupplement.resx -source_lang = ja - -[opentween.AuthDialog] -file_filter = OpenTween/AuthDialog..resx -source_file = OpenTween/AuthDialog.resx -source_lang = ja - -[opentween.EventViewerDialog] -file_filter = OpenTween/EventViewerDialog..resx -source_file = OpenTween/EventViewerDialog.resx -source_lang = ja - -[opentween.FilterDialog] -file_filter = OpenTween/FilterDialog..resx -source_file = OpenTween/FilterDialog.resx -source_lang = ja - -[opentween.FormInfo] -file_filter = OpenTween/FormInfo..resx -source_file = OpenTween/FormInfo.resx -source_lang = ja - -[opentween.HashtagManage] -file_filter = OpenTween/HashtagManage..resx -source_file = OpenTween/HashtagManage.resx -source_lang = ja - -[opentween.InputTabName] -file_filter = OpenTween/InputTabName..resx -source_file = OpenTween/InputTabName.resx -source_lang = ja - -[opentween.ListAvailable] -file_filter = OpenTween/ListAvailable..resx -source_file = OpenTween/ListAvailable.resx -source_lang = ja - -[opentween.ListManage] -file_filter = OpenTween/ListManage..resx -source_file = OpenTween/ListManage.resx -source_lang = ja - -[opentween.MyLists] -file_filter = OpenTween/MyLists..resx -source_file = OpenTween/MyLists.resx -source_lang = ja - -[opentween.OpenURL] -file_filter = OpenTween/OpenURL..resx -source_file = OpenTween/OpenURL.resx -source_lang = ja - -[opentween.SearchWord] -file_filter = OpenTween/SearchWord..resx -source_file = OpenTween/SearchWord.resx -source_lang = ja - -[opentween.ShowUserInfo] -file_filter = OpenTween/ShowUserInfo..resx -source_file = OpenTween/ShowUserInfo.resx -source_lang = ja - -[opentween.TabsDialog] -file_filter = OpenTween/TabsDialog..resx -source_file = OpenTween/TabsDialog.resx -source_lang = ja - -[opentween.Tween] -file_filter = OpenTween/Tween..resx -source_file = OpenTween/Tween.resx -source_lang = ja - -[opentween.TweenAboutBox] -file_filter = OpenTween/TweenAboutBox..resx -source_file = OpenTween/TweenAboutBox.resx -source_lang = ja - -[opentween.UpdateDialog] -file_filter = OpenTween/UpdateDialog..resx -source_file = OpenTween/UpdateDialog.resx -source_lang = ja - diff --git a/packages/.gitignore b/packages/.gitignore deleted file mode 100644 index 72e8ffc0d..000000000 --- a/packages/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* From f8abeda73d5cbf063645b6c4695524b09e836cf0 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 04:33:09 +0900 Subject: [PATCH 254/402] =?UTF-8?q?=E3=83=93=E3=83=AB=E3=83=89=E6=99=82?= =?UTF-8?q?=E3=81=ABResXcueTask=E3=81=AB=E9=96=A2=E3=81=99=E3=82=8B?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=81=8C=E9=81=A9=E7=94=A8=E3=81=95=E3=82=8C?= =?UTF-8?q?=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: f9a20054 ("OpenTween.csprojを新しい形式に") --- OpenTween/OpenTween.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/OpenTween/OpenTween.csproj b/OpenTween/OpenTween.csproj index 414945b28..8582dfe3a 100644 --- a/OpenTween/OpenTween.csproj +++ b/OpenTween/OpenTween.csproj @@ -1,4 +1,5 @@ - + + WinExe true @@ -646,6 +647,7 @@ + From 6921345124fee34cc8920965566d8616fa4e5a56 Mon Sep 17 00:00:00 2001 From: kzrnm Date: Sun, 25 Sep 2022 00:55:46 +0900 Subject: [PATCH 255/402] =?UTF-8?q?=E7=94=BB=E5=83=8F=E3=82=92=E3=82=AF?= =?UTF-8?q?=E3=83=AA=E3=83=83=E3=83=97=E3=83=9C=E3=83=BC=E3=83=89=E3=81=AB?= =?UTF-8?q?=E3=82=B3=E3=83=94=E3=83=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/TweetThumbnail.Designer.cs | 9 +++++++++ OpenTween/TweetThumbnail.cs | 13 +++++++++++++ OpenTween/TweetThumbnail.en.resx | 2 ++ OpenTween/TweetThumbnail.resx | 4 ++++ 4 files changed, 28 insertions(+) diff --git a/OpenTween/TweetThumbnail.Designer.cs b/OpenTween/TweetThumbnail.Designer.cs index 702d66159..aa2d5e9c4 100644 --- a/OpenTween/TweetThumbnail.Designer.cs +++ b/OpenTween/TweetThumbnail.Designer.cs @@ -39,6 +39,7 @@ private void InitializeComponent() this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.searchImageGoogleMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.searchImageSauceNaoMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.copyToClipboardMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.contextMenuStrip.SuspendLayout(); this.SuspendLayout(); // @@ -63,6 +64,7 @@ private void InitializeComponent() this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.openMenuItem, this.copyUrlMenuItem, + this.copyToClipboardMenuItem, this.toolStripSeparator1, this.searchImageGoogleMenuItem, this.searchImageSauceNaoMenuItem}); @@ -99,6 +101,12 @@ private void InitializeComponent() this.searchImageSauceNaoMenuItem.Name = "searchImageSauceNaoMenuItem"; this.searchImageSauceNaoMenuItem.Click += new System.EventHandler(this.SearchImageSauceNaoMenuItem_Click); // + // copyToClipboardMenuItem + // + resources.ApplyResources(this.copyToClipboardMenuItem, "copyToClipboardMenuItem"); + this.copyToClipboardMenuItem.Name = "copyToClipboardMenuItem"; + this.copyToClipboardMenuItem.Click += new System.EventHandler(this.CopyToClipboardMenuItem_Click); + // // TweetThumbnail // resources.ApplyResources(this, "$this"); @@ -122,6 +130,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem searchImageSauceNaoMenuItem; private System.Windows.Forms.ToolStripMenuItem openMenuItem; private System.Windows.Forms.ToolStripMenuItem copyUrlMenuItem; + private System.Windows.Forms.ToolStripMenuItem copyToClipboardMenuItem; private System.Windows.Forms.ToolStripSeparator toolStripSeparator1; } } diff --git a/OpenTween/TweetThumbnail.cs b/OpenTween/TweetThumbnail.cs index c3b839918..96bc6f170 100644 --- a/OpenTween/TweetThumbnail.cs +++ b/OpenTween/TweetThumbnail.cs @@ -299,6 +299,19 @@ private void CopyUrlMenuItem_Click(object sender, EventArgs e) MessageBox.Show(ex.Message); } } + + private void CopyToClipboardMenuItem_Click(object sender, EventArgs e) + { + try + { + if (this.PictureBox[this.scrollBar.Value].Image is { } memoryImage) + Clipboard.SetImage(memoryImage.Image); + } + catch (ExternalException ex) + { + MessageBox.Show(ex.Message); + } + } } public class ThumbnailDoubleClickEventArgs : EventArgs diff --git a/OpenTween/TweetThumbnail.en.resx b/OpenTween/TweetThumbnail.en.resx index 33aefc088..43d6d93ac 100644 --- a/OpenTween/TweetThumbnail.en.resx +++ b/OpenTween/TweetThumbnail.en.resx @@ -10,6 +10,8 @@ 254, 22 &Copy URL + 254, 22 + Copy image to clipboard 254, 22 &Open diff --git a/OpenTween/TweetThumbnail.resx b/OpenTween/TweetThumbnail.resx index bbac2ffd1..96bcd4631 100644 --- a/OpenTween/TweetThumbnail.resx +++ b/OpenTween/TweetThumbnail.resx @@ -16,6 +16,8 @@ System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 copyUrlMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + copyToClipboardMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 openMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelPictureBox @@ -39,6 +41,8 @@ 110, 17 223, 22 URLをコピー(&C) + 223, 22 + 画像をクリップボードにコピー 223, 22 開く(&O) Fill From 1c2dca1b90d69106c6912b3475e6703a34d1b544 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 04:31:26 +0900 Subject: [PATCH 256/402] =?UTF-8?q?=E3=82=B5=E3=83=A0=E3=83=8D=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E7=94=BB=E5=83=8F=E3=81=AE=E3=82=B3=E3=83=B3=E3=83=86?= =?UTF-8?q?=E3=82=AD=E3=82=B9=E3=83=88=E3=83=A1=E3=83=8B=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E3=81=AE=E3=82=AD=E3=83=A3=E3=83=97=E3=82=B7=E3=83=A7=E3=83=B3?= =?UTF-8?q?=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/TweetThumbnail.en.resx | 6 +++--- OpenTween/TweetThumbnail.resx | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenTween/TweetThumbnail.en.resx b/OpenTween/TweetThumbnail.en.resx index 43d6d93ac..788138f7c 100644 --- a/OpenTween/TweetThumbnail.en.resx +++ b/OpenTween/TweetThumbnail.en.resx @@ -8,10 +8,10 @@ 255, 98 - 254, 22 - &Copy URL 254, 22 - Copy image to clipboard + Copy image + 254, 22 + &Copy image URL 254, 22 &Open diff --git a/OpenTween/TweetThumbnail.resx b/OpenTween/TweetThumbnail.resx index 96bcd4631..79421639b 100644 --- a/OpenTween/TweetThumbnail.resx +++ b/OpenTween/TweetThumbnail.resx @@ -14,10 +14,10 @@ System.Windows.Forms.UserControl, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 contextMenuStrip System.Windows.Forms.ContextMenuStrip, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - copyUrlMenuItem - System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 copyToClipboardMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + copyUrlMenuItem + System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 openMenuItem System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 panelPictureBox @@ -39,10 +39,10 @@ 224, 98 110, 17 - 223, 22 - URLをコピー(&C) 223, 22 - 画像をクリップボードにコピー + 画像をコピー + 223, 22 + 画像のURLをコピー(&C) 223, 22 開く(&O) Fill From a49d5fcaac2fab458cc2d572dc7ce9fc0f22b5b8 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 04:48:01 +0900 Subject: [PATCH 257/402] =?UTF-8?q?ChangeLog=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 6921345124fee34cc8920965566d8616fa4e5a56 での変更を反映 --- OpenTween/Resources/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 3c93aae43..b3a85ab2e 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -1,6 +1,7 @@ 更新履歴 ==== Unreleased + * NEW: サムネイル画像のコンテキストメニューに「画像をコピー」を追加 (thx @kzlogos!) ==== Ver 2.7.1(2022/09/03) * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) From a2b3a9bf44668cef5bd364400fb213620234982e Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Thu, 1 Dec 2022 05:18:31 +0900 Subject: [PATCH 258/402] =?UTF-8?q?=E3=82=B5=E3=83=A0=E3=83=8D=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E7=94=BB=E5=83=8F=E3=81=AE=E3=82=B3=E3=83=B3=E3=83=86?= =?UTF-8?q?=E3=82=AD=E3=82=B9=E3=83=88=E3=83=A1=E3=83=8B=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E9=A0=85=E7=9B=AE=E3=81=AE=E9=A0=86=E5=BA=8F=E3=82=92=E5=A4=89?= =?UTF-8?q?=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/TweetThumbnail.Designer.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/OpenTween/TweetThumbnail.Designer.cs b/OpenTween/TweetThumbnail.Designer.cs index aa2d5e9c4..481575f9e 100644 --- a/OpenTween/TweetThumbnail.Designer.cs +++ b/OpenTween/TweetThumbnail.Designer.cs @@ -35,11 +35,11 @@ private void InitializeComponent() this.panelPictureBox = new System.Windows.Forms.Panel(); this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); this.openMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.copyToClipboardMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.copyUrlMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.searchImageGoogleMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.searchImageSauceNaoMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.copyToClipboardMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.contextMenuStrip.SuspendLayout(); this.SuspendLayout(); // @@ -63,8 +63,8 @@ private void InitializeComponent() resources.ApplyResources(this.contextMenuStrip, "contextMenuStrip"); this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.openMenuItem, - this.copyUrlMenuItem, this.copyToClipboardMenuItem, + this.copyUrlMenuItem, this.toolStripSeparator1, this.searchImageGoogleMenuItem, this.searchImageSauceNaoMenuItem}); @@ -78,6 +78,12 @@ private void InitializeComponent() this.openMenuItem.Name = "openMenuItem"; this.openMenuItem.Click += new System.EventHandler(this.OpenMenuItem_Click); // + // copyToClipboardMenuItem + // + resources.ApplyResources(this.copyToClipboardMenuItem, "copyToClipboardMenuItem"); + this.copyToClipboardMenuItem.Name = "copyToClipboardMenuItem"; + this.copyToClipboardMenuItem.Click += new System.EventHandler(this.CopyToClipboardMenuItem_Click); + // // copyUrlMenuItem // resources.ApplyResources(this.copyUrlMenuItem, "copyUrlMenuItem"); @@ -101,12 +107,6 @@ private void InitializeComponent() this.searchImageSauceNaoMenuItem.Name = "searchImageSauceNaoMenuItem"; this.searchImageSauceNaoMenuItem.Click += new System.EventHandler(this.SearchImageSauceNaoMenuItem_Click); // - // copyToClipboardMenuItem - // - resources.ApplyResources(this.copyToClipboardMenuItem, "copyToClipboardMenuItem"); - this.copyToClipboardMenuItem.Name = "copyToClipboardMenuItem"; - this.copyToClipboardMenuItem.Click += new System.EventHandler(this.CopyToClipboardMenuItem_Click); - // // TweetThumbnail // resources.ApplyResources(this, "$this"); From ecdd09f89c989ff4dbae56224cb7e83eaa7522d9 Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Fri, 2 Dec 2022 05:28:34 +0900 Subject: [PATCH 259/402] =?UTF-8?q?GitHub=20Actions=E3=81=A7=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E5=A4=B1=E6=95=97=E6=99=82=E3=81=AE=E7=B5=82?= =?UTF-8?q?=E4=BA=86=E3=82=B3=E3=83=BC=E3=83=89=E3=81=8C=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=96=E3=81=AE=E6=88=90=E5=90=A6=E3=81=AB=E5=8F=8D=E6=98=A0?= =?UTF-8?q?=E3=81=95=E3=82=8C=E3=81=AA=E3=81=84=E5=95=8F=E9=A1=8C=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a7de4ede0..ad475e3ad 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,7 +89,7 @@ jobs: $altCoverPath = "$($env:NUGET_PACKAGES)\altcover\$($altCoverVersion)\tools\$($targetFramework)\AltCover.exe" $xunitPath = "$($env:NUGET_PACKAGES)\xunit.runner.console\$($xunitVersion)\tools\$($targetFramework)\xunit.console.exe" - Start-Process ` + $p = Start-Process ` -FilePath $altCoverPath ` -ArgumentList ( '--inputDirectory', @@ -105,9 +105,14 @@ jobs: '--visibleBranches' ) ` -NoNewWindow ` + -PassThru ` -Wait - Start-Process ` + if ($p.ExitCode -ne 0) { + exit $p.ExitCode + } + + $p = Start-Process ` -FilePath $altCoverPath ` -ArgumentList ( 'runner', @@ -119,8 +124,13 @@ jobs: '.\__Instrumented\OpenTween.Tests.dll' ) ` -NoNewWindow ` + -PassThru ` -Wait + if ($p.ExitCode -ne 0) { + exit $p.ExitCode + } + - name: Upload test results to codecov shell: pwsh run: | From d2422c2b896c2dea0697d0b972219704ef1aaf62 Mon Sep 17 00:00:00 2001 From: niyari Date: Tue, 10 Jan 2023 04:59:17 +0900 Subject: [PATCH 260/402] =?UTF-8?q?twitter=20/=20twemoji=20=E3=81=AECDN?= =?UTF-8?q?=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween.Tests/TweetExtractorTest.cs | 28 +++++++++++++-------------- OpenTween.Tests/TweetFormatterTest.cs | 4 ++-- OpenTween/TweetExtractor.cs | 3 ++- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/OpenTween.Tests/TweetExtractorTest.cs b/OpenTween.Tests/TweetExtractorTest.cs index 942440d46..29aa41ec0 100644 --- a/OpenTween.Tests/TweetExtractorTest.cs +++ b/OpenTween.Tests/TweetExtractorTest.cs @@ -191,7 +191,7 @@ public void ExtractEmojiEntities_Test() Assert.Equal(new[] { 5, 6 }, entity.Indices); Assert.Equal("✨", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/2728.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/2728.png", entity.Url); } [Fact] @@ -202,7 +202,7 @@ public void ExtractEmojiEntities_SurrogatePairTest() // 「𠮷」「🍚」は UTF-16 でそれぞれ 2byte になるがインデックスはコードポイント単位で数えなければならない Assert.Equal(new[] { 4, 5 }, entity.Indices); Assert.Equal("🍚", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f35a.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f35a.png", entity.Url); } [Fact] @@ -224,7 +224,7 @@ public void ExtractEmojiEntities_VariationSelector_EmojiStyleTest() Assert.Equal(new[] { 0, 2 }, entity.Indices); Assert.Equal("©", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/a9.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/a9.png", entity.Url); } [Fact] @@ -238,7 +238,7 @@ public void ExtractEmojiEntities_VariationSelector_UnnecessaryEmojiStyleTest() Assert.Equal(new[] { 0, 1 }, entities[0].Indices); Assert.Equal("🍣", entities[0].Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f363.png", entities[0].Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f363.png", entities[0].Url); Assert.Equal(new[] { 1, 2 }, entities[1].Indices); Assert.Equal("", entities[1].Text); @@ -253,7 +253,7 @@ public void ExtractEmojiEntities_CombiningCharacterTest() Assert.Equal(new[] { 0, 2 }, entity.Indices); Assert.Equal("#⃣", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/23-20e3.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/23-20e3.png", entity.Url); } [Fact] @@ -265,7 +265,7 @@ public void ExtractEmojiEntities_Unicode10Test() Assert.Equal(new[] { 0, 1 }, entity.Indices); Assert.Equal("🦒", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f992.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f992.png", entity.Url); } [Fact] @@ -277,7 +277,7 @@ public void ExtractEmojiEntities_Unicode11Test() Assert.Equal(new[] { 0, 1 }, entity.Indices); Assert.Equal("🦸", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f9b8.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f9b8.png", entity.Url); } [Fact] @@ -289,7 +289,7 @@ public void ExtractEmojiEntities_Unicode12Test() Assert.Equal(new[] { 0, 1 }, entity.Indices); Assert.Equal("🧅", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f9c5.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f9c5.png", entity.Url); } [Fact] @@ -301,7 +301,7 @@ public void ExtractEmojiEntities_Unicode13Test() Assert.Equal(new[] { 0, 1 }, entity.Indices); Assert.Equal("🥷", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f977.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f977.png", entity.Url); } [Fact] @@ -313,7 +313,7 @@ public void ExtractEmojiEntities_Unicode14Test() Assert.Equal(new[] { 0, 1 }, entity.Indices); Assert.Equal("🫠", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1fae0.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1fae0.png", entity.Url); } [Fact] @@ -325,7 +325,7 @@ public void ExtractEmojiEntities_EmojiModifiers_CombiningTest() Assert.Equal(new[] { 0, 2 }, entity.Indices); Assert.Equal("👦\U0001F3FF", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f466-1f3ff.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f466-1f3ff.png", entity.Url); } [Fact] @@ -337,7 +337,7 @@ public void ExtractEmojiEntities_EmojiModifiers_SingleTest() Assert.Equal(new[] { 0, 1 }, entity.Indices); Assert.Equal("\U0001F3FF", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f3ff.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f3ff.png", entity.Url); } [Fact] @@ -349,7 +349,7 @@ public void ExtractEmojiEntities_EmojiZWJSequenceTest() Assert.Equal(new[] { 0, 3 }, entity.Indices); Assert.Equal("👨\u200D🎨", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f468-200d-1f3a8.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f468-200d-1f3a8.png", entity.Url); } [Fact] @@ -362,7 +362,7 @@ public void ExtractEmojiEntities_EmojiZWJSequenceWithVariationSelectorTest() Assert.Equal(new[] { 0, 4 }, entity.Indices); Assert.Equal("🏃\u200D♀\uFE0F", entity.Text); - Assert.Equal("https://twemoji.maxcdn.com/2/72x72/1f3c3-200d-2640-fe0f.png", entity.Url); + Assert.Equal("https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f3c3-200d-2640-fe0f.png", entity.Url); } } } diff --git a/OpenTween.Tests/TweetFormatterTest.cs b/OpenTween.Tests/TweetFormatterTest.cs index c8c8ebaa9..8902c96a5 100644 --- a/OpenTween.Tests/TweetFormatterTest.cs +++ b/OpenTween.Tests/TweetFormatterTest.cs @@ -175,11 +175,11 @@ public void FormatEmojiEntity_Test() { Indices = new[] { 0, 1 }, Text = "🍣", - Url = "https://twemoji.maxcdn.com/2/72x72/1f363.png", + Url = "https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/1f363.png", }, }; - var expected = "\"🍣\""; + var expected = "\"🍣\""; Assert.Equal(expected, TweetFormatter.AutoLinkHtml(text, entities)); } diff --git a/OpenTween/TweetExtractor.cs b/OpenTween/TweetExtractor.cs index da822153d..df1cf25ac 100644 --- a/OpenTween/TweetExtractor.cs +++ b/OpenTween/TweetExtractor.cs @@ -189,7 +189,8 @@ public static IEnumerable ExtractEmojiEntities(string text) { Indices = new[] { startPos, endPos }, Text = input, - Url = "https://twemoji.maxcdn.com/2/72x72/" + string.Join("-", codepointHex) + ".png", + // TODO: CDN(MaxCDN)の廃止のため一時的に変更。 https://twemoji.maxcdn.com/2/72x72/ + Url = "https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/72x72/" + string.Join("-", codepointHex) + ".png", }; } else From 54f93a52b2ba2140802274fe9ef7a60c3e6c2bae Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 11 Jan 2023 03:16:52 +0900 Subject: [PATCH 261/402] =?UTF-8?q?ChangeLog=20=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit d2422c2b896c2dea0697d0b972219704ef1aaf62 での変更を反映 --- OpenTween/Resources/ChangeLog.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index b3a85ab2e..32333f557 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Unreleased * NEW: サムネイル画像のコンテキストメニューに「画像をコピー」を追加 (thx @kzlogos!) + * CHG: Twemojiの画像の取得元をMaxCDNからCloudflareに移行 (thx @sou_niyari!) ==== Ver 2.7.1(2022/09/03) * FIX: 発言一覧の選択位置を移動した際にデッドロックが発生する場合がある不具合を修正 (thx @Kazuki_Ashiya!) From f7dc599083a20e98a1acba0b392c5d233c20cb5b Mon Sep 17 00:00:00 2001 From: Kimura Youichi Date: Wed, 11 Jan 2023 03:59:47 +0900 Subject: [PATCH 262/402] =?UTF-8?q?WebBrowser=E3=82=B3=E3=83=B3=E3=83=9D?= =?UTF-8?q?=E3=83=BC=E3=83=8D=E3=83=B3=E3=83=88=E5=86=85=E3=81=A7=E3=81=AE?= =?UTF-8?q?=E3=82=AB=E3=83=A9=E3=83=BC=E7=B5=B5=E6=96=87=E5=AD=97=E3=81=AE?= =?UTF-8?q?=E6=8F=8F=E7=94=BB=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OpenTween/Resources/ChangeLog.txt | 1 + OpenTween/Tween.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/OpenTween/Resources/ChangeLog.txt b/OpenTween/Resources/ChangeLog.txt index 32333f557..c8bc34ac6 100644 --- a/OpenTween/Resources/ChangeLog.txt +++ b/OpenTween/Resources/ChangeLog.txt @@ -2,6 +2,7 @@ ==== Unreleased * NEW: サムネイル画像のコンテキストメニューに「画像をコピー」を追加 (thx @kzlogos!) + * NEW: Segoe UI Emoji によるカラー絵文字の描画に対応(発言詳細欄のみ) * CHG: Twemojiの画像の取得元をMaxCDNからCloudflareに移行 (thx @sou_niyari!) ==== Ver 2.7.1(2022/09/03) diff --git a/OpenTween/Tween.cs b/OpenTween/Tween.cs index 5cc1ace7e..5e65deaf5 100644 --- a/OpenTween/Tween.cs +++ b/OpenTween/Tween.cs @@ -101,7 +101,7 @@ public partial class TweenMain : OTBaseForm "" + "