OSDN Git Service

スクリーンリーダーで引用ツイートの内容が発言一覧上でも読み上げられるように修正
authorKimura Youichi <kim.upsilon@bucyou.net>
Tue, 31 May 2016 14:52:09 +0000 (23:52 +0900)
committerKimura Youichi <kim.upsilon@bucyou.net>
Tue, 31 May 2016 14:52:19 +0000 (23:52 +0900)
ListViewSubItem に AccessibleName 等が用意されていないため、SubItem の Text には
PostClass.AccessibleText を代入し、MyList_DrawSubItem で画面上に描画する際には
PostClass.TextSingleLine を使用することで擬似的に実現した。

OpenTween/Models/PostClass.cs
OpenTween/Properties/Resources.Designer.cs
OpenTween/Properties/Resources.en.resx
OpenTween/Properties/Resources.resx
OpenTween/Resources/ChangeLog.txt
OpenTween/Tween.cs
OpenTween/Twitter.cs

index d029e44..da03914 100644 (file)
@@ -65,6 +65,10 @@ namespace OpenTween.Models
         }
         public string Nickname { get; set; }
         public string TextFromApi { get; set; }
+
+        /// <summary>スクリーンリーダーでの読み上げを考慮したテキスト</summary>
+        public string AccessibleText { get; set; }
+
         public string ImageUrl { get; set; }
         public string ScreenName { get; set; }
         public DateTime CreatedAt { get; set; }
index 993a125..e648846 100644 (file)
@@ -1966,6 +1966,15 @@ namespace OpenTween.Properties {
         }
         
         /// <summary>
+        ///   [引用 @{0}: {1}] に類似しているローカライズされた文字列を検索します。
+        /// </summary>
+        internal static string QuoteStatus_AccessibleText {
+            get {
+                return ResourceManager.GetString("QuoteStatus_AccessibleText", resourceCulture);
+            }
+        }
+        
+        /// <summary>
         ///   Direct Messageの送受信をするため、もう一度認証処理をして下さい。 に類似しているローカライズされた文字列を検索します。
         /// </summary>
         internal static string ReAuthorizeText {
index e50e967..028ab9d 100644 (file)
@@ -1137,4 +1137,7 @@ Available service: {1}</value>
   <data name="AddNewTab_ListView_AccessibleName" xml:space="preserve">
     <value>PostsList</value>
   </data>
+  <data name="QuoteStatus_AccessibleText" xml:space="preserve">
+    <value>[Quote @{0}: {1}]</value>
+  </data>
 </root>
\ No newline at end of file
index af51693..e87f17d 100644 (file)
   <data name="AddNewTab_ListView_AccessibleName" xml:space="preserve">
     <value>発言一覧</value>
   </data>
+  <data name="QuoteStatus_AccessibleText" xml:space="preserve">
+    <value>[引用 @{0}: {1}]</value>
+  </data>
 </root>
\ No newline at end of file
index fa1d568..aa596ce 100644 (file)
@@ -5,6 +5,7 @@
   - 「絵文字を画像で表示する(Twemoji)」が有効な場合に Unicode 8.0 で追加された絵文字が表示されるようになります
  * NEW: pic.twitter.com の画像アップロード時に代替テキストを送信できるようになりました
   - 代替テキストについては https://blog.twitter.com/ja/2016/0330alt を参照して下さい
+ * NEW: スクリーンリーダーで引用ツイートの内容が発言一覧上でも読み上げられるようになりました
 
 ==== Ver 1.3.2(2016/04/12)
  * NEW: touch.pixiv.net のサムネイル表示に対応 (pixiv.net は既に対応しています)
index 1f2228a..31187a1 100644 (file)
@@ -4911,7 +4911,7 @@ namespace OpenTween
             {
                 string[] sitem= {"",
                                  Post.Nickname,
-                                 Post.IsDeleted ? "(DELETED)" : Post.TextSingleLine,
+                                 Post.IsDeleted ? "(DELETED)" : Post.AccessibleText,
                                  Post.CreatedAt.ToString(this._cfgCommon.DateTimeFormat),
                                  Post.ScreenName,
                                  "",
@@ -4923,7 +4923,7 @@ namespace OpenTween
             {
                 string[] sitem = {"",
                                   Post.Nickname,
-                                  Post.IsDeleted ? "(DELETED)" : Post.TextSingleLine,
+                                  Post.IsDeleted ? "(DELETED)" : Post.AccessibleText,
                                   Post.CreatedAt.ToString(this._cfgCommon.DateTimeFormat),
                                   Post.ScreenName + Environment.NewLine + "(RT:" + Post.RetweetedBy + ")",
                                   "",
@@ -4932,6 +4932,7 @@ namespace OpenTween
                 itm = new ImageListViewItem(sitem, this.IconCache, Post.ImageUrl);
             }
             itm.StateIndex = Post.StateIndex;
+            itm.Tag = Post;
 
             bool read = Post.IsRead;
             //未読管理していなかったら既読として扱う
@@ -5034,6 +5035,8 @@ namespace OpenTween
             if (e.ColumnIndex > 0)
             {
                 //アイコン以外の列
+                var post = (PostClass)e.Item.Tag;
+
                 RectangleF rct = e.Bounds;
                 rct.Width = e.Header.Width;
                 int fontHeight = e.Item.Font.Height;
@@ -5090,7 +5093,7 @@ namespace OpenTween
                         using (Font fnt = new Font(e.Item.Font, FontStyle.Bold))
                         {
                             TextRenderer.DrawText(e.Graphics,
-                                                    e.Item.SubItems[2].Text,
+                                                    post.TextSingleLine,
                                                     e.Item.Font,
                                                     Rectangle.Round(rct),
                                                     color,
@@ -5112,7 +5115,7 @@ namespace OpenTween
                     else if (drawLineCount == 1)
                     {
                         TextRenderer.DrawText(e.Graphics,
-                                                e.SubItem.Text,
+                                                e.ColumnIndex != 2 ? e.SubItem.Text : post.TextSingleLine,
                                                 e.Item.Font,
                                                 Rectangle.Round(rct),
                                                 color,
@@ -5125,7 +5128,7 @@ namespace OpenTween
                     else
                     {
                         TextRenderer.DrawText(e.Graphics,
-                                                e.SubItem.Text,
+                                                e.ColumnIndex != 2 ? e.SubItem.Text : post.TextSingleLine,
                                                 e.Item.Font,
                                                 Rectangle.Round(rct),
                                                 color,
index 132228c..4fd61c5 100644 (file)
@@ -759,6 +759,9 @@ namespace OpenTween
             post.TextFromApi = this.ReplaceTextFromApi(post.TextFromApi, entities);
             post.TextFromApi = WebUtility.HtmlDecode(post.TextFromApi);
             post.TextFromApi = post.TextFromApi.Replace("<3", "\u2661");
+            post.AccessibleText = this.CreateAccessibleText(textFromApi, entities, (status.RetweetedStatus ?? status).QuotedStatus);
+            post.AccessibleText = WebUtility.HtmlDecode(post.AccessibleText);
+            post.AccessibleText = post.AccessibleText.Replace("<3", "\u2661");
 
             post.QuoteStatusIds = GetQuoteTweetStatusIds(entities)
                 .Where(x => x != post.StatusId && x != post.RetweetedId)
@@ -1117,6 +1120,9 @@ namespace OpenTween
                     post.TextFromApi = this.ReplaceTextFromApi(textFromApi, message.Entities);
                     post.TextFromApi = WebUtility.HtmlDecode(post.TextFromApi);
                     post.TextFromApi = post.TextFromApi.Replace("<3", "\u2661");
+                    post.AccessibleText = this.CreateAccessibleText(textFromApi, message.Entities, quoteStatus: null);
+                    post.AccessibleText = WebUtility.HtmlDecode(post.AccessibleText);
+                    post.AccessibleText = post.AccessibleText.Replace("<3", "\u2661");
                     post.IsFav = false;
 
                     post.QuoteStatusIds = GetQuoteTweetStatusIds(message.Entities).Distinct().ToArray();
@@ -1247,17 +1253,53 @@ namespace OpenTween
                 {
                     foreach (var m in entities.Media)
                     {
-                        if (m.AltText != null)
-                        {
-                            text = text.Replace(m.Url, string.Format(Properties.Resources.ImageAltText, m.AltText));
-                        }
-                        else
+                        if (!string.IsNullOrEmpty(m.DisplayUrl)) text = text.Replace(m.Url, m.DisplayUrl);
+                    }
+                }
+            }
+            return text;
+        }
+
+        private string CreateAccessibleText(string text, TwitterEntities entities, TwitterStatus quoteStatus)
+        {
+            if (entities == null)
+                return text;
+
+            if (entities.Urls != null)
+            {
+                foreach (var entity in entities.Urls)
+                {
+                    if (quoteStatus != null)
+                    {
+                        var matchStatusUrl = Twitter.StatusUrlRegex.Match(entity.ExpandedUrl);
+                        if (matchStatusUrl.Success && matchStatusUrl.Groups["StatusId"].Value == quoteStatus.IdStr)
                         {
-                            if (!string.IsNullOrEmpty(m.DisplayUrl)) text = text.Replace(m.Url, m.DisplayUrl);
+                            var quoteText = this.CreateAccessibleText(quoteStatus.Text, quoteStatus.MergedEntities, quoteStatus: null);
+                            text = text.Replace(entity.Url, $"[引用 @{quoteStatus.User.ScreenName}: {quoteText}]");
                         }
                     }
+                    else if (!string.IsNullOrEmpty(entity.DisplayUrl))
+                    {
+                        text = text.Replace(entity.Url, entity.DisplayUrl);
+                    }
                 }
             }
+
+            if (entities.Media != null)
+            {
+                foreach (var entity in entities.Media)
+                {
+                    if (!string.IsNullOrEmpty(entity.AltText))
+                    {
+                        text = text.Replace(entity.Url, string.Format(Properties.Resources.ImageAltText, entity.AltText));
+                    }
+                    else if (!string.IsNullOrEmpty(entity.DisplayUrl))
+                    {
+                        text = text.Replace(entity.Url, entity.DisplayUrl);
+                    }
+                }
+            }
+
             return text;
         }