diff --git a/Src/xWorks/ConfiguredLcmGenerator.cs b/Src/xWorks/ConfiguredLcmGenerator.cs index 047a475ce6..891ceaea1e 100644 --- a/Src/xWorks/ConfiguredLcmGenerator.cs +++ b/Src/xWorks/ConfiguredLcmGenerator.cs @@ -2804,11 +2804,7 @@ private static void GenerateRunWithPossibleLink(GeneratorSettings settings, stri } if (!String.IsNullOrEmpty(style)) { - var cssStyle = CssGenerator.GenerateCssStyleFromLcmStyleSheet(style, - settings.Cache.WritingSystemFactory.GetWsFromStr(writingSystem), settings.PropertyTable); - var css = cssStyle.ToString(); - if (!String.IsNullOrEmpty(css)) - settings.ContentGenerator.SetRunStyle(writer, config, css); + settings.ContentGenerator.SetRunStyle(writer, config, settings.PropertyTable, writingSystem, style, false); } if (linkDestination != Guid.Empty) { @@ -3025,13 +3021,7 @@ private static void GenerateError(string text, IFragmentWriter writer, Generator { var writingSystem = settings.Cache.WritingSystemFactory.GetStrFromWs(settings.Cache.WritingSystemFactory.UserWs); settings.ContentGenerator.StartRun(writer, writingSystem); - // Make the error red and slightly larger than the surrounding text - var css = new StyleDeclaration - { - new ExCSS.Property("color") { Term = new HtmlColor(222, 0, 0) }, - new ExCSS.Property("font-size") { Term = new PrimitiveTerm(UnitType.Ems, 1.5f) } - }; - settings.ContentGenerator.SetRunStyle(writer, null, css.ToString()); + settings.ContentGenerator.SetRunStyle(writer, null, settings.PropertyTable, writingSystem, null, true); if (text.Contains(TxtLineSplit)) { var txtContents = text.Split(TxtLineSplit); diff --git a/Src/xWorks/ILcmContentGenerator.cs b/Src/xWorks/ILcmContentGenerator.cs index e9b9301ee3..0b74607f3f 100644 --- a/Src/xWorks/ILcmContentGenerator.cs +++ b/Src/xWorks/ILcmContentGenerator.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Text; using System.Web.UI.WebControls; +using XCore; namespace SIL.FieldWorks.XWorks { @@ -33,7 +34,7 @@ IFragment GenerateGroupingNode(object field, string className, ConfigurableDicti void EndBiDiWrapper(IFragmentWriter writer); void StartRun(IFragmentWriter writer, string writingSystem); void EndRun(IFragmentWriter writer); - void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode config, string css); + void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode config, ReadOnlyPropertyTable propertyTable, string writingSystem, string runStyle, bool error); void StartLink(IFragmentWriter writer, ConfigurableDictionaryNode config, Guid destination); void StartLink(IFragmentWriter writer, ConfigurableDictionaryNode config, string externalDestination); void EndLink(IFragmentWriter writer); diff --git a/Src/xWorks/LcmJsonGenerator.cs b/Src/xWorks/LcmJsonGenerator.cs index a033b42400..84a30f1e74 100644 --- a/Src/xWorks/LcmJsonGenerator.cs +++ b/Src/xWorks/LcmJsonGenerator.cs @@ -181,10 +181,17 @@ public void EndRun(IFragmentWriter writer) m_runBuilder.Value.Clear(); } - public void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode config, string css) + public void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode config, ReadOnlyPropertyTable propertyTable, string writingSystem, string runStyle, bool error) { - if(!string.IsNullOrEmpty(css)) - ((JsonFragmentWriter)writer).InsertJsonProperty("style", css); + if (!string.IsNullOrEmpty(runStyle)) + { + var cache = propertyTable.GetValue("cache", null); + var cssStyle = CssGenerator.GenerateCssStyleFromLcmStyleSheet(runStyle, + cache.WritingSystemFactory.GetWsFromStr(writingSystem), propertyTable); + string css = cssStyle?.ToString(); + if (!string.IsNullOrEmpty(css)) + ((JsonFragmentWriter)writer).InsertJsonProperty("style", css); + } } public void StartLink(IFragmentWriter writer, ConfigurableDictionaryNode config, Guid destination) diff --git a/Src/xWorks/LcmWordGenerator.cs b/Src/xWorks/LcmWordGenerator.cs index 448c55f70b..819faa1194 100644 --- a/Src/xWorks/LcmWordGenerator.cs +++ b/Src/xWorks/LcmWordGenerator.cs @@ -677,14 +677,27 @@ public void EndRun(IFragmentWriter writer) // Beginning a new run is sufficient to end the old run // and to ensure new styles/content are applied to the new run. } - public void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode config, string css) - { - // TODO: Many runs don't ever call this function; this is not where we want to set the character styles. - /*if (config != null && !string.IsNullOrEmpty(config.Style)) + /// + /// Set the style for a specific run. + /// This is needed to set the specific style for any field that allows the + /// default style to be overridden (Table Cell, Custom Field, Note...). + /// + public void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode config, ReadOnlyPropertyTable propertyTable, string writingSystem, string runStyle, bool error) + { + if (!string.IsNullOrEmpty(runStyle)) { - ((WordFragmentWriter)writer).WordFragment.AddStyleLink(config.Style, ConfigurableDictionaryNode.StyleTypes.Character); - }*/ + // Add the style link. + ((WordFragmentWriter)writer).WordFragment.AddStyleLink(runStyle, ConfigurableDictionaryNode.StyleTypes.Character); + + // Only add the style to the styleSheet if not already there. + if (!_styleSheet.ChildElements.Any(p => ((Style)p).StyleId == runStyle)) + { + int ws = Cache.WritingSystemFactory.GetWsFromStr(writingSystem); + var wpStyle = WordStylesGenerator.GenerateWordStyleFromLcmStyleSheet(runStyle, ws, _propertyTable); + _styleSheet.Append(wpStyle); + } + } } public void StartLink(IFragmentWriter writer, ConfigurableDictionaryNode config, Guid destination) { @@ -751,9 +764,20 @@ public void StartTableRow(IFragmentWriter writer) } public void AddTableCell(IFragmentWriter writer, bool isHead, int colSpan, HorizontalAlign alignment, IFragment content) { - WP.TableCell tableCell = new WP.TableCell(); - tableCell.Append(new WP.Paragraph(new WP.Run(new WP.Text(content.ToString())))); - ((WordFragmentWriter)writer).CurrentTableRow.Append(tableCell); + // The runs contain the text and any cell-specific styling (in the run properties). + // Note: multiple runs will exist if the cell contains multiple styles. + WP.Paragraph paragraph = new WP.Paragraph(); + foreach (WP.Run run in ((DocFragment)content).DocBody.Elements()) + { + paragraph.Append(run.CloneNode(true)); + } + + if (paragraph.HasChildren) + { + WP.TableCell tableCell = new WP.TableCell(); + tableCell.Append(paragraph); + ((WordFragmentWriter)writer).CurrentTableRow.Append(tableCell); + } } public void EndTableRow(IFragmentWriter writer) { diff --git a/Src/xWorks/LcmXhtmlGenerator.cs b/Src/xWorks/LcmXhtmlGenerator.cs index 7489d971e4..df48443425 100644 --- a/Src/xWorks/LcmXhtmlGenerator.cs +++ b/Src/xWorks/LcmXhtmlGenerator.cs @@ -2,6 +2,7 @@ // This software is licensed under the LGPL, version 2.1 or later // (http://www.gnu.org/licenses/lgpl-2.1.html) +using ExCSS; using Icu.Collation; using SIL.FieldWorks.Common.Controls; using SIL.FieldWorks.Common.FwUtils; @@ -732,9 +733,29 @@ public void EndRun(IFragmentWriter writer) ((XmlFragmentWriter)writer).Writer.WriteEndElement(); // span } - public void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode config, string css) + public void SetRunStyle(IFragmentWriter writer, ConfigurableDictionaryNode config, ReadOnlyPropertyTable propertyTable, string writingSystem, string runStyle, bool error) { - ((XmlFragmentWriter)writer).Writer.WriteAttributeString("style", css); + StyleDeclaration cssStyle = null; + + // This is primarily intended to make formatting errors stand out in the GUI. + // Make the error red and slightly larger than the surrounding text. + if (error) + { + cssStyle = new StyleDeclaration + { + new ExCSS.Property("color") { Term = new HtmlColor(222, 0, 0) }, + new ExCSS.Property("font-size") { Term = new PrimitiveTerm(ExCSS.UnitType.Ems, 1.5f) } + }; + } + else if (!string.IsNullOrEmpty(runStyle)) + { + var cache = propertyTable.GetValue("cache", null); + cssStyle = CssGenerator.GenerateCssStyleFromLcmStyleSheet(runStyle, + cache.WritingSystemFactory.GetWsFromStr(writingSystem), propertyTable); + } + string css = cssStyle?.ToString(); + if (!String.IsNullOrEmpty(css)) + ((XmlFragmentWriter)writer).Writer.WriteAttributeString("style", css); } public void StartLink(IFragmentWriter writer, ConfigurableDictionaryNode config, Guid destination)