OSDN Git Service

7f2fa759 の変更がタブ名の重複を考慮していない問題を修正 (thx @5px!)
authorKimura Youichi <kim.upsilon@bucyou.net>
Mon, 10 Feb 2014 00:50:08 +0000 (09:50 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Mon, 10 Feb 2014 01:01:01 +0000 (10:01 +0900)
OpenTween.Tests/OpenTween.Tests.csproj
OpenTween.Tests/TabInformationTest.cs [new file with mode: 0644]
OpenTween/OpenTween.csproj
OpenTween/Properties/Resources.Designer.cs
OpenTween/Properties/Resources.en.resx
OpenTween/Properties/Resources.resx
OpenTween/StatusDictionary.cs
OpenTween/TabException.cs [new file with mode: 0644]
OpenTween/Tween.cs

index 3df4f4e..4e8cbc7 100644 (file)
@@ -67,6 +67,7 @@
     <Compile Include="PostClassTest.cs" />
     <Compile Include="PostFilterRuleVersion113DeserializeTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TabInformationTest.cs" />
     <Compile Include="TabsDialogTest.cs" />
     <Compile Include="TestUtils.cs" />
     <Compile Include="Thumbnail\Services\ImgAzyobuziNetTest.cs" />
diff --git a/OpenTween.Tests/TabInformationTest.cs b/OpenTween.Tests/TabInformationTest.cs
new file mode 100644 (file)
index 0000000..ac0afc7
--- /dev/null
@@ -0,0 +1,82 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2014 kim_upsilon (@kim_upsilon) <https://upsilo.net/~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 <http://www.gnu.org/licenses/>, 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.Reflection;
+using System.Text;
+using Xunit;
+using Xunit.Extensions;
+
+namespace OpenTween
+{
+    public class TabInformationTest
+    {
+        private TabInformations tabinfo;
+
+        public TabInformationTest()
+        {
+            this.tabinfo = Activator.CreateInstance(typeof(TabInformations), true) as TabInformations;
+
+            // 標準のタブを追加
+            this.tabinfo.AddTab("Recent", MyCommon.TabUsageType.Home, null);
+            this.tabinfo.AddTab("Reply", MyCommon.TabUsageType.Mentions, null);
+            this.tabinfo.AddTab("DM", MyCommon.TabUsageType.DirectMessage, null);
+            this.tabinfo.AddTab("Favorites", MyCommon.TabUsageType.Favorites, null);
+
+            // TabInformation.GetInstance() で取得できるようにする
+            var field = typeof(TabInformations).GetField("_instance",
+                BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.SetField);
+            field.SetValue(null, this.tabinfo);
+        }
+
+        [Fact]
+        public void MakeTabName_Test()
+        {
+            var baseTabName = "NewTab";
+            Assert.Equal("NewTab", this.tabinfo.MakeTabName(baseTabName, 5));
+        }
+
+        [Fact]
+        public void MakeTabName_RetryTest()
+        {
+            this.tabinfo.AddTab("NewTab", MyCommon.TabUsageType.UserDefined, null);
+            this.tabinfo.AddTab("NewTab2", MyCommon.TabUsageType.UserDefined, null);
+
+            var baseTabName = "NewTab";
+            Assert.Equal("NewTab3", this.tabinfo.MakeTabName(baseTabName, 5));
+        }
+
+        [Fact]
+        public void MakeTabName_RetryErrorTest()
+        {
+            this.tabinfo.AddTab("NewTab", MyCommon.TabUsageType.UserDefined, null);
+            this.tabinfo.AddTab("NewTab2", MyCommon.TabUsageType.UserDefined, null);
+            this.tabinfo.AddTab("NewTab3", MyCommon.TabUsageType.UserDefined, null);
+            this.tabinfo.AddTab("NewTab4", MyCommon.TabUsageType.UserDefined, null);
+            this.tabinfo.AddTab("NewTab5", MyCommon.TabUsageType.UserDefined, null);
+
+            var baseTabName = "NewTab";
+            Assert.Throws<TabException>(() => this.tabinfo.MakeTabName(baseTabName, 5));
+        }
+    }
+}
index e79252f..e0d7dbf 100644 (file)
     <Compile Include="Setting\Panel\TweetPrvPanel.Designer.cs">
       <DependentUpon>TweetPrvPanel.cs</DependentUpon>
     </Compile>
+    <Compile Include="TabException.cs" />
     <Compile Include="TabsDialog.cs">
       <SubType>Form</SubType>
     </Compile>
index 6bc058f..d5d6286 100644 (file)
@@ -2611,6 +2611,15 @@ namespace OpenTween.Properties {
         }
         
         /// <summary>
+        ///   タブ &quot;{0}&quot; が既に存在するため追加できません。同名のタブを削除して再度やり直して下さい。 に類似しているローカライズされた文字列を検索します。
+        /// </summary>
+        internal static string TabNameDuplicate_Text {
+            get {
+                return ResourceManager.GetString("TabNameDuplicate_Text", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   タブ &quot;&quot;{0}&quot;&quot; は既に存在するため、変更できません。別の名前を指定してください。 に類似しているローカライズされた文字列を検索します。
         /// </summary>
         internal static string Tabs_DoubleClickText1 {
index d3e8667..c197001 100644 (file)
   <data name="OpenURL_LoadFailed" xml:space="preserve">
     <value>Failed to load the tweet. ({0})</value>
   </data>
+  <data name="TabNameDuplicate_Text" xml:space="preserve">
+    <value>The tab "{0}" was already exists. Please remove the tab and try again.</value>
+  </data>
 </root>
\ No newline at end of file
index a6462b0..ade9bc6 100644 (file)
   <data name="OpenURL_LoadFailed" xml:space="preserve">
     <value>ツイートの取得に失敗しました ({0})</value>
   </data>
+  <data name="TabNameDuplicate_Text" xml:space="preserve">
+    <value>タブ "{0}" が既に存在するため追加できません。同名のタブを削除して再度やり直して下さい。</value>
+  </data>
 </root>
\ No newline at end of file
index d872e71..64b1d03 100644 (file)
@@ -510,6 +510,42 @@ namespace OpenTween
             return _tabs.ContainsValue(ts);
         }
 
+        /// <summary>
+        /// 指定されたタブ名を元に、既存のタブ名との重複を避けた名前を生成します
+        /// </summary>
+        /// <param name="baseTabName">作成したいタブ名</param>
+        /// <returns>生成されたタブ名</returns>
+        /// <exception cref="TabException">タブ名の生成を 100 回試行して失敗した場合</exception>
+        public string MakeTabName(string baseTabName)
+        {
+            return this.MakeTabName(baseTabName, 100);
+        }
+
+        /// <summary>
+        /// 指定されたタブ名を元に、既存のタブ名との重複を避けた名前を生成します
+        /// </summary>
+        /// <param name="baseTabName">作成したいタブ名</param>
+        /// <param name="retryCount">重複を避けたタブ名を生成する試行回数</param>
+        /// <returns>生成されたタブ名</returns>
+        /// <exception cref="TabException">retryCount で指定された回数だけタブ名の生成を試行して失敗した場合</exception>
+        public string MakeTabName(string baseTabName, int retryCount)
+        {
+            if (!this.ContainsTab(baseTabName))
+                return baseTabName;
+
+            foreach (var i in Enumerable.Range(2, retryCount - 1))
+            {
+                var tabName = baseTabName + i;
+                if (!this.ContainsTab(tabName))
+                {
+                    return tabName;
+                }
+            }
+
+            var message = string.Format(Properties.Resources.TabNameDuplicate_Text, baseTabName);
+            throw new TabException(message);
+        }
+
         public Dictionary<string, TabClass> Tabs
         {
             get
diff --git a/OpenTween/TabException.cs b/OpenTween/TabException.cs
new file mode 100644 (file)
index 0000000..46c62e0
--- /dev/null
@@ -0,0 +1,38 @@
+// OpenTween - Client of Twitter
+// Copyright (c) 2014 kim_upsilon (@kim_upsilon) <https://upsilo.net/~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 <http://www.gnu.org/licenses/>, 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;
+
+namespace OpenTween
+{
+    /// <summary>
+    /// タブの操作時に問題が発生した場合にスローされる例外
+    /// </summary>
+    public class TabException : Exception
+    {
+        public TabException() : base() { }
+        public TabException(string message) : base(message) { }
+        public TabException(string message, Exception innerException) : base(message, innerException) { }
+    }
+}
index 5c73ce3..0890ba5 100644 (file)
@@ -7783,7 +7783,14 @@ namespace OpenTween
 
                         return;
                     }
-                    this.OpenRelatedTab(t.Result);
+                    try
+                    {
+                        this.OpenRelatedTab(t.Result);
+                    }
+                    catch (TabException ex)
+                    {
+                        MessageBox.Show(this, ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+                    }
                 }, uiScheduler);
         }
 
@@ -12497,18 +12504,31 @@ namespace OpenTween
         {
             if (this.ExistCurrentPost && !_curPost.IsDm)
             {
-                this.OpenRelatedTab(this._curPost);
+                try
+                {
+                    this.OpenRelatedTab(this._curPost);
+                }
+                catch (TabException ex)
+                {
+                    MessageBox.Show(this, ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+                }
             }
         }
 
+        /// <summary>
+        /// 指定されたツイートに対する関連発言タブを開きます
+        /// </summary>
+        /// <param name="post">表示する対象となるツイート</param>
+        /// <exception cref="TabException">名前の重複が多すぎてタブを作成できない場合</exception>
         private void OpenRelatedTab(PostClass post)
         {
-            const string tabName = "Related Tweets";
-
             var tabRelated = this._statuses.GetTabByType(MyCommon.TabUsageType.Related);
+            string tabName;
 
             if (tabRelated == null)
             {
+                tabName = this._statuses.MakeTabName("Related Tweets");
+
                 this.AddNewTab(tabName, false, MyCommon.TabUsageType.Related);
                 this._statuses.AddTab(tabName, MyCommon.TabUsageType.Related, null);
 
@@ -12516,6 +12536,10 @@ namespace OpenTween
                 tabRelated.UnreadManage = false;
                 tabRelated.Notify = false;
             }
+            else
+            {
+                tabName = tabRelated.TabName;
+            }
 
             tabRelated.RelationTargetPost = post;
             this.ClearTab(tabName, false);