Skip to content
This repository was archived by the owner on Oct 4, 2021. It is now read-only.

Commit ef6da16

Browse files
authored
Merge pull request #8991 from mono/new-project-dialog-incorrect-language-read-by-voiceover
[Ide] Fix incorrect language read by voice over in New Project dialog
2 parents b81ea0f + fcd3ab3 commit ef6da16

File tree

4 files changed

+109
-19
lines changed

4 files changed

+109
-19
lines changed

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkNewProjectDialogBackend.UI.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,18 @@ partial class GtkNewProjectDialogBackend : IdeDialog
5858
TreeStore templateCategoriesTreeStore =
5959
new TreeStore(typeof (string), typeof (Xwt.Drawing.Image), typeof(TemplateCategory));
6060
TreeView templatesTreeView;
61-
const int TemplateNameColumn = 0;
61+
// DO NOT REMOVE
62+
// This column is not used here, but is required for
63+
// external UI tests which need a plain string name inside the model
64+
// This is a reminder to not remove or abuse this column for other purposes
65+
const int TemplateNameColumn = 0;
66+
// DO NOT REMOVE
6267
const int TemplateIconColumn = 1;
6368
const int TemplateColumn = 2;
69+
const int TemplateOwnCategoryNameColumn = 3;
70+
const int TemplateA11yLanguageNameColumn = 4;
6471
TreeStore templatesTreeStore =
65-
new TreeStore(typeof (string), typeof (Xwt.Drawing.Image), typeof(SolutionTemplate));
72+
new TreeStore(typeof (string), typeof (Xwt.Drawing.Image), typeof(SolutionTemplate), typeof (string), typeof (string));
6673
VBox templateVBox;
6774
ImageView templateImage;
6875
Label templateNameLabel;

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkNewProjectDialogBackend.cs

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public GtkNewProjectDialogBackend ()
5454
// Set up the list store so the test framework can work out the correct columns
5555
SemanticModelAttribute modelAttr = new SemanticModelAttribute ("templateCategoriesListStore__Name", "templateCategoriesListStore__Icon", "templateCategoriesListStore__Category");
5656
TypeDescriptor.AddAttributes (templateCategoriesTreeStore, modelAttr);
57-
modelAttr = new SemanticModelAttribute ("templateListStore__Name", "templateListStore__Icon", "templateListStore__Template");
57+
modelAttr = new SemanticModelAttribute ("templateListStore__Name", "templateListStore__Icon", "templateListStore__Template", "templateListStore__Category", "templateListStore__Language");
5858
TypeDescriptor.AddAttributes (templatesTreeStore, modelAttr);
5959

6060
templateCategoriesTreeView.Selection.Changed += TemplateCategoriesTreeViewSelectionChanged;
@@ -138,14 +138,16 @@ static void SetTemplateTextCellData (TreeViewColumn col, CellRenderer renderer,
138138
var templateTextRenderer = (GtkTemplateCellRenderer)renderer;
139139
templateTextRenderer.Template = template;
140140
templateTextRenderer.TemplateIcon = model.GetValue (it, TemplateIconColumn) as Xwt.Drawing.Image;
141-
templateTextRenderer.TemplateCategory = model.GetValue (it, TemplateNameColumn) as string;
141+
templateTextRenderer.TemplateCategory = model.GetValue (it, TemplateOwnCategoryNameColumn) as string;
142142
}
143143

144144
static void SetLanguageCellData (TreeViewColumn col, CellRenderer renderer, TreeModel model, TreeIter it)
145145
{
146146
var template = (SolutionTemplate)model.GetValue (it, TemplateColumn);
147+
var language = (string)model.GetValue (it, TemplateA11yLanguageNameColumn);
147148
var languageRenderer = (LanguageCellRenderer)renderer;
148149
languageRenderer.Template = template;
150+
languageRenderer.SelectedLanguage = language ?? template?.Language ?? string.Empty;
149151
}
150152

151153
void HandlePopup (SolutionTemplate template, uint eventTime)
@@ -228,6 +230,8 @@ void AddLanguageMenuItems (Xwt.Menu menu, SolutionTemplate template)
228230
languageCellRenderer.SelectedLanguage = language;
229231
controller.SelectedLanguage = language;
230232
templatesTreeView.QueueDraw ();
233+
if (templatesTreeView.Selection.GetSelected (out var selIter))
234+
templatesTreeStore.SetValue (selIter, TemplateA11yLanguageNameColumn, languageCellRenderer.SelectedLanguage);
231235
ShowSelectedTemplate ();
232236
};
233237
menu.Items.Add (menuItem);
@@ -390,38 +394,58 @@ void ShowTemplatesForCategory (TemplateCategory category)
390394
languageCellRenderer.RenderRecentTemplate = false;
391395
foreach (TemplateCategory subCategory in category.Categories) {
392396
var iter = templatesTreeStore.AppendValues (
393-
MarkupTopLevelCategoryName (subCategory.Name),
397+
subCategory.Name,
394398
null,
399+
null,
400+
subCategory.Name,
395401
null);
396402

397403
foreach (SolutionTemplate template in subCategory.Templates) {
398404
if (template.HasProjects || controller.IsNewSolution) {
405+
string language = GetLanguageForTemplate (template);
399406
templatesTreeStore.AppendValues (
400407
iter,
401408
template.Name,
402409
GetIcon (template.IconId, IconSize.Dnd),
403-
template);
410+
template,
411+
subCategory.Name,
412+
language);
404413
}
405414
}
406415
}
407416
templatesTreeView.ExpandAll ();
408-
}
409-
417+
}
418+
419+
string GetLanguageForTemplate (SolutionTemplate template)
420+
{
421+
string language = controller.SelectedLanguage;
422+
if (template.AvailableLanguages.Contains (language)) {
423+
return language;
424+
}
425+
426+
return template.AvailableLanguages.OrderBy (item => item).FirstOrDefault ();
427+
}
428+
410429
void ShowRecentTemplates ()
411430
{
412431
templateTextRenderer.RenderRecentTemplate = true;
413-
languageCellRenderer.RenderRecentTemplate = true;
432+
languageCellRenderer.RenderRecentTemplate = true;
433+
var subCategoryName = Core.GettextCatalog.GetString ("Recently used templates");
414434
var iter = templatesTreeStore.AppendValues (
415-
MarkupTopLevelCategoryName (Core.GettextCatalog.GetString ("Recently used templates")),
435+
subCategoryName,
436+
null,
416437
null,
438+
subCategoryName,
417439
null);
418440
foreach (SolutionTemplate template in controller.RecentTemplates) {
419441
if (template.HasProjects || controller.IsNewSolution) {
420442
templatesTreeStore.AppendValues (
421443
iter,
422-
controller.GetCategoryPathText (template),
444+
template.Name,
423445
GetIcon (template.IconId, IconSize.Dnd),
424-
template);
446+
template,
447+
controller.GetCategoryPathText (template),
448+
template.Language);
425449
}
426450
}
427451
templatesTreeView.ExpandAll ();
@@ -460,6 +484,13 @@ SolutionTemplate GetSelectedTemplate ()
460484

461485
void ShowTemplate (SolutionTemplate template)
462486
{
487+
string language = GetLanguageForTemplate (controller.SelectedTemplate);
488+
489+
TreeIter item;
490+
if (templatesTreeView.Selection.GetSelected (out item)) {
491+
templatesTreeStore.SetValue (item, TemplateA11yLanguageNameColumn, language);
492+
}
493+
463494
templateNameLabel.Markup = MarkupTemplateName (template.Name);
464495
templateDescriptionLabel.Text = template.Description;
465496
templateImage.Image = controller.GetImage (template);

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/GtkTemplateCellRenderer.cs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,47 @@ class GtkTemplateCellRenderer : CellRendererText
4040
{
4141
const int iconTextPadding = 9;
4242
int groupTemplateHeadingTotalYPadding = 24;
43-
int recentTemplateHeadingTotalYPadding = 30;
43+
int recentTemplateHeadingTotalYPadding = 30;
44+
private SolutionTemplate template;
45+
private string templateCategory;
46+
private string selectedLanguage;
4447
const int groupTemplateHeadingYOffset = 4;
4548
const int categoryTextPaddingX = 4;
4649

47-
public SolutionTemplate Template { get; set; }
48-
public string SelectedLanguage { get; set; }
50+
public SolutionTemplate Template {
51+
get { return template; }
52+
set {
53+
template = value;
54+
SetAccessibilityText ();
55+
}
56+
}
57+
public string SelectedLanguage {
58+
get { return selectedLanguage; }
59+
set {
60+
selectedLanguage = value;
61+
SetAccessibilityText ();
62+
}
63+
}
4964
public Xwt.Drawing.Image TemplateIcon { get; set; }
50-
public string TemplateCategory { get; set; }
65+
public string TemplateCategory {
66+
get { return templateCategory; }
67+
set {
68+
templateCategory = value;
69+
SetAccessibilityText ();
70+
}
71+
}
5172
public bool RenderRecentTemplate { get; set; }
5273

74+
void SetAccessibilityText ()
75+
{
76+
Text = template?.Name ?? string.Empty;
77+
if (!string.IsNullOrEmpty (templateCategory)) {
78+
if (!string.IsNullOrEmpty (Text))
79+
Text += ", ";
80+
Text += templateCategory.Replace ("→", "–"); // we don't want narrators to read "right arrow"
81+
}
82+
}
83+
5384
public GtkTemplateCellRenderer ()
5485
{
5586
if (IsYosemiteOrHigher ()) {
@@ -102,7 +133,7 @@ void DrawTemplateCategoryText (Drawable window, Widget widget, Rectangle cell_ar
102133
int textPixelWidth = widget.Allocation.Width - ((int)Xpad * 2);
103134
layout.Width = (int)(textPixelWidth * Pango.Scale.PangoScale);
104135

105-
layout.SetMarkup (TemplateCategory);
136+
layout.SetMarkup (MarkupTopLevelCategoryName (TemplateCategory));
106137

107138
int w, h;
108139
layout.GetPixelSize (out w, out h);
@@ -182,6 +213,11 @@ static StateType GetState (Widget widget, CellRendererState flags)
182213
stateType = widget.HasFocus ? StateType.Selected : StateType.Active;
183214
return stateType;
184215
}
216+
217+
static string MarkupTopLevelCategoryName (string name)
218+
{
219+
return "<span font_weight='bold'>" + GLib.Markup.EscapeText (name) + "</span>";
220+
}
185221
}
186222
}
187223

main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/LanguageCellRenderer.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,34 @@ class LanguageCellRenderer : CellRendererText
4545

4646
int minLanguageRectWidth;
4747

48-
public SolutionTemplate Template { get; set; }
48+
SolutionTemplate template;
49+
50+
public SolutionTemplate Template {
51+
get { return template; }
52+
set {
53+
template = value;
54+
Text = GetAccessibleLanguageName ();
55+
}
56+
}
57+
4958
string selectedLanguage;
5059
public string SelectedLanguage {
5160
get {
5261
return selectedLanguage;
5362
}
5463
set {
5564
selectedLanguage = value;
56-
Text = GetAccessibleLanguageName (value);
65+
Text = GetAccessibleLanguageName (selectedLanguage);
5766
}
5867
}
5968

69+
string GetAccessibleLanguageName ()
70+
{
71+
if (template == null)
72+
return string.Empty;
73+
return GetAccessibleLanguageName (GetSelectedLanguage ());
74+
}
75+
6076
internal static string GetAccessibleLanguageName (string language)
6177
{
6278
switch (language) {

0 commit comments

Comments
 (0)